Receive OAuth2 Token from XHR Request - javascript
I am trying to get an OAuth2 Token via XHR-Request in TypeScript like mentioned on this side(https://developer.paypal.com/docs/integration/direct/make-your-first-call/). My code so far:
var clientID = <clientID>;
var secret = <mySecret>;
var oReq = new XMLHttpRequest();
oReq.open("POST", "https://api.sandbox.paypal.com/v1/oauth2/token", true);
oReq.setRequestHeader('grant_type', "client_credentials");
oReq.setRequestHeader('Username', this.clientID);
oReq.setRequestHeader('Password', this.secret);
oReq.setRequestHeader('Content-type', "application/x-www-form-urlencoded");
oReq.setRequestHeader('Accept', "application/json");
oReq.setRequestHeader('Accept-Language', "en_US");
oReq.onreadystatechange = function () {
if (oReq.readyState === 4) {
if (oReq.status === 200) {
console.log(oReq.responseText);
} else {
console.log("Error: " + oReq.status);
}
}
console.log("Status: " + oReq.status);
};
console.log("Status: " + oReq.status);
oReq.send();
Sadly I keep getting 401 as response. I already tried the curl command with the same clientID and secret, which worked for me. Can someone tell me whats wrong with me code?
The request you’re getting the 401 response for isn’t your POST request but instead the CORS preflight OPTIONS request that the browser automatically does on its own.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests has details about what triggers browsers to do a preflight but what it comes down to in this specific case is that you’re adding grant_type, Username, and Password request headers to the request in order to do the authentication needed—but your browser makes the preflight OPTIONS request without those headers (because the purpose of the preflight is to ask the server to indicate whether it’s OK with receiving requests that include those request headers).
And so what happens is the following (reproduced using curl just for illustration purposes):
$ curl -X OPTIONS -i -H "Origin: http://example.com" \
'https://api.sandbox.paypal.com/v1/oauth2/token'
HTTP/1.1 401 Unauthorized
Date: Wed, 09 Aug 2017 09:08:32 GMT
Server: Apache
paypal-debug-id: f8963606c5654
Access-Control-Allow-Origin: http://example.com
Access-Control-Expose-Headers: False
HTTP_X_PP_AZ_LOCATOR: sandbox.slc
Paypal-Debug-Id: f8963606c5654
Set-Cookie: X-PP-SILOVER=name%3DSANDBOX3.API.1%26silo_version%3D1880%26app%3Dapiplatformproxyserv%26TIME%3D282167897%26HTTP_X_PP_AZ_LOCATOR%3Dsandbox.slc; Expires=Wed, 09 Aug 2017 09:38:32 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT
Content-Length: 0
Connection: close
Content-Type: text/plain; charset=ISO-8859-1
That is, the https://api.sandbox.paypal.com/v1/oauth2/token endpoint apparently requires authentication even for OPTIONS requests. Because it does, there’s no way you can make POST requests to that endpoint directly from your frontend JavaScript code running in a browser.
So you’ll instead need to make the request from your backend code.
Related
Csrf verification failed - Django Rest and Backbone.js [duplicate]
This question already has answers here: Got CSRF verification failure when while requesting POST through API (2 answers) Closed 5 years ago. I have started going through "Lightweight Django" https://github.com/lightweightdjango to learn more about Django and Client-Side JavaScript. During testing out the LoginView created using Backbone.js I get the Forbidden(403) CSRF verification failed.Request aborted. message, as pointed out in this post: CSRF verification failing in django/backbone.js . First of all I thought of inserting {% csrf_token %} template tag in the form but when I do this the server is giving me a POST / HTTP/1.1" 405 0 - Method Not Allowed (POST) : / message. Since the AJAX X-CSRFToken request header is being set using $.ajaxPrefilter(), I can't figure out what the problem is. When I am using httpie to perform POST requests using the superuser details, everything works just fine as in the following example: HTTP/1.0 200 OK Allow: POST, OPTIONS Content-Type: application/json Date: Mon, 11 Sep 2017 13:49:49 GMT Server: WSGIServer/0.2 CPython/3.6.2 Vary: Cookie X-Frame-Options: SAMEORIGIN { "token" : some_value } Making use of the console from the "Inspect Element" feature I get the following messages: Response headers: Allow: GET, HEAD, OPTIONS Content-Length: 0 Content-Type: text/html; charset=utf-8 Date: Mon, 11 Sep 2017 14:03:06 GMT Server: WSGIServer/0.2 CPython/3.6.2 X-Frame-Options: SAMEORIGIN Request headers: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.5 Connection: keep-alive Content-Length: 116 Content-Type: application/x-www-form-urlencoded Cookie: csrftoken=some_value Host: 127.0.0.1:8000 Referer: http://127.0.0.1:8000/ Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:55.0) Gecko/20100101 Firefox/55.0 I don't know if the TemplateView is to blame or I am missing something: urls.py: from django.conf.urls import url,include from django.views.generic import TemplateView #from django.views.decorators.csrf import ensure_csrf_cookie from rest_framework.authtoken.views import obtain_auth_token from board.urls import router urlpatterns = [ url(r'^api-auth/', obtain_auth_token, name='api-login'), url(r'^api-root/', include(router.urls)), url(r'^$', TemplateView.as_view(template_name='board/index.html')), ] Can someone explain what is actually going on? Thanks!
Fore every POST request you need to send CSRF token to your django backend in Django weebasite u can fined ajaxSetup for your frontend (backbone.js). Just create new file ajaxSetup.js and past this code. function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } function sameOrigin(url) { // test that a given url is a same-origin URL // url could be relative or scheme relative or absolute var host = document.location.host; // host + port var protocol = document.location.protocol; var sr_origin = '//' + host; var origin = protocol + sr_origin; // Allow absolute or scheme relative URLs to same origin return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') || // or any other URL that isn't scheme relative or absolute i.e relative. !(/^(\/\/|http:|https:).*/.test(url)); } $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) { // Send the token to same-origin, relative URLs only. // Send the token only if the method warrants CSRF protection // Using the CSRFToken value acquired earlier xhr.setRequestHeader("X-CSRFToken", csrftoken); } } }); You can read about this in django official website CSRF TOKEN
JavaScript gets null response or empty responseXML from Python SimpleXMLRPCServer
I found the answer to this question. It is resolved. Narrative: I am accessing a Python API, a set of methodCalls on top of SimpleXMLRPCServer. Server responds to browser GET request with a html page, "web_interface.html". The HTML page is a very simple script that sends a XHR POST request of xml params to the XMLRPC server. Server responds to XHR POST with headers but empty document. Server responds to cURL with correct data. Why is JavaScript not getting any readable data in response from server? | web_interface.html | <!DOCTYPE html> <html> <head> <script> var xrequest = '<?xml version="1.0?"><methodCall><methodName>helloWorld<methodName><params><param><firstWord><string>hello</string><firstWord></param><param><secondWord><string>world</string></secondWord></param></params></methodCall>'; function hello() { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { alert(this.responseText); alert(this.status); alert(this.response); } } xhr.open('POST', '/', true); xhr.setRequestHeader("Authorization", "Basic " + "aGVsbG8=" + ":" + "dGVzdA=="); xhr.send(xrequest); } </script> </head> <body> <div> <h2 id="msgoutput">HelloWorld API Test</h2> <button type="button" onclick="hello(); return false;">SAY HELLO!</button> </div> </body> </html> Note: Clicking the button produces the alert dialogs. Status dialog shows "200" while Text and response dialogs are null. | Mozilla Inspector Data & Headers | POST Raw Data: <?xml version="1.0?"><methodCall><methodName>helloWorld<methodName><params><param><firstWord><string>hello</string><firstWord></param><param><secondWord><string>world</string></secondWord></param></params></methodCall> Response Headers: Content-Length 332 Content-Type text/html Date Sat, 10 Dec 2016 23:51:21 GMT Server BaseHTTP/0.3 Python/2.7.12 Request Headers: Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Encoding gzip, deflate Accept-Language en-US,en;q=0.5 AuthorizationBasic aGVsbG8=:dGVzdA== (not my actual creds, swapped fakes) Connection keep-alive Content-Length 218 Content-Type text/plain;charset=UTF-8 DNT1 Hostlocalhost:8442 Referer http://localhost:8442/ User-Agent Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0 | Test with cURL | :~$ curl -i --data '<?xml version="1.0"?><methodCall><methodName>helloWorld</methodName><params><param><firstWord><string>hello</string></firstWord></param><param><secondWord><string>world</string></secondWord></param></params></methodCall>' http://username:password#localhost:8442 HTTP/1.0 200 OK Server: BaseHTTP/0.3 Python/2.7.12 Date: Sun, 11 Dec 2016 00:00:13 GMT Content-type: text/html Content-length: 137 <?xml version='1.0'?> <methodResponse> <params> <param> <value><string>hello-world</string></value> </param> </params> </methodResponse> Note: No problem, cURL returns the XML response as text. I pointed cURL at a netcat socket to see exactly what it is sending to the XMLRPC server. Here's what netcat shows when cURL hits: | cURL POST Data | POST / HTTP/1.1 Host: localhost:8442 Authorization: Basic YWRtaW46Z2liYmVyc2g= User-Agent: curl/7.47.0 Accept: */* Content-Length: 220 Content-Type: application/x-www-form-urlencoded <?xml version="1.0"?><methodCall><methodName>helloWorld</methodName><params><param><firstWord><string>hello</string></firstWord></param><param><secondWord><string>world</string></secondWord></param></params></methodCall> It's not CORS. Already tested a GET request to xhr.responseText with same browser on same machine. Setup is using same host, same port, same directory for both the GET page and the XHR POST XMLRPC request. What am I missing?
The Python SimpleXMLRPCServer had some code hacked into it to handle cookies. Problem is, the code couldn't handle the cookie objects when a browser makes connection. This code threw an error on each invocation. It was stopping the server from sending the response text to the browser. I learned this after writing a Python snippet to output debug information to a file. I removed the cookie code and then the response XML was successfully sent from the server to the browser. I also discovered that sending the username/password from the XHR Send statement would throw an authentication error from the server. The server is expecting credentials to be in the POST header as Authentication: Basic base64 [btoa(username:password)]. The content-type header was not the culprit in this case. Now content-type is set to text/xml on both client and server. Here is the modified JavaScript code that works: <!DOCTYPE html> <html> <head> <script> var xrequest = '<?xml version="1.0"?><methodCall><methodName>helloWorld</methodName><params><param><firstWord><string>hello</string></firstWord></param><param><secondWord><string>world</string></secondWord></param></params></methodCall>'; function hello() { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (this.readyState == XMLHttpRequest.DONE) { } } xhr.open("POST", "/", true); xhr.setRequestHeader("Authorization", "Basic " + btoa("admin" + ":" + "1234")); xhr.setRequestHeader("Content-Type", "text/xml") xhr.send(xrequest); } </script> </head> <body> <div> <h2 id="msgoutput">HelloWorld API Test</h2> <button type="button" onclick="hello(); return false;">SAY HELLO!</button> </div> </body> </html>
Get data with $resource from Flask API in AngularjJS
I'm using a Flask rest api where I've a method that I call from AngularJS with $resource factory. I'm using now data to try it, this is the simplified code in the server: return jsonify({'teacher': 'Tom'}) And in AngularJS, in a controller where I want to get data: var teacher = $resource('http://localhost:8001/entities/teacher/:id'); teacher.get({id: 1}).$promise.then(function(teacher) { // success $scope.teacher = teacher; }, function(errResponse) { // fail console.log('fail') console.log(errResponse) }); And this is the log in web browser console: fail Object { data: null, status: -1, headers: fd/<(), config: Object, statusText: "" } But however I can see the request in network console with data in response with 200 status code, because of this I think that I don't know how read this data from $resource response, I've search info about this but I don't know how if I can see the data the resource give mi a fail error. Any idea? I know that I should to have this code in a service in another file, it's only a sample to find the solution. Thanks! Update: I think that the problem is in the headers that I received from the server. If I try to use $http with a url that I found as example this work perfect, but when I try the same with my own server this fail even though I can see the response (and it's fine in the network console and it's fine with curl test) I think that the problem is in the headers, maybe $http or $resource needs a specific headers. I' ve updated the original question, I hope that someone can help me. I'm sure that the response is application/json. This is the test url: http://jsonplaceholder.typicode.com/users and the header that is returned is: Cache-Control public, max-age=14400 Content-Encoding gzip Content-Type application/json; charset=utf-8 Date Mon, 03 Oct 2016 07:43:11 GMT Etag W/"160d-MxiAGkI3ZBrjm0xiEDfwqw" Expires Mon, 03 Oct 2016 11:43:11 GMT Pragma no-cache Server cloudflare-nginx Vary Accept-Encoding Via 1.1 vegur X-Firefox-Spdy h2 X-Powered-By Express access-control-allow-credentials true cf-cache-status HIT cf-ray 2ebec303f9f72f7d-MAD x-content-type-options nosniff And my header is: Cache-Control no-cache Content-Length 35 Content-Type application/json Date Mon, 03 Oct 2016 08:26:00 GMT Expires Fri, 01 Jan 1990 00:00:00 GMT Link Server Development/2.0 I'm using a Google App Engine developer Server (I don't know if this is relevant).
CORS Request - Terminal Works, Browser Fails
I'm trying to fetch an image via ajax from an amazon server. That server is configured to return the Access-Control-Allow-Origin: * header. The issue is that when I do the request from terminal, I see the response fine. But when I do the AJAX request from browser, I'm blocked and I don't see that header on the response. Terminal request: ➜ ~ curl -sI -H "Origin: google.com" -H "Access-Control-Request-Method: GET" http://my-domain/my-image.jpg HTTP/1.1 200 OK Content-Type: image/jpeg Content-Length: 595284 Connection: close Date: Thu, 13 Aug 2015 12:28:02 GMT Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST Access-Control-Max-Age: 3000 Content-Disposition: attachment; filename="Hydrangeas.jpg" Last-Modified: Thu, 13 Aug 2015 07:00:21 GMT x-amz-version-id: null ETag: "bdf3bf1da3405725be763540d6601144" Server: AmazonS3 Age: 4132 X-Cache: Hit from cloudfront Via: 1.1 b7b782c917cd62c6605a1684c071a774.cloudfront.net (CloudFront) X-Amz-Cf-Id: 7t1gB74LHHWEIXcl_ml6pWC9voDrfSakCMUJ2KeAjMYZ-37aZYmPcg== When I try from Chrome/FF (haven't tried others), I see the canonical error message and when I look in the network tab I don't see the ACAA header: XMLHttpRequest cannot load ***. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '***' is therefore not allowed access. This is the code I use to try and get the image: var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if (this.readyState === 4 && this.status === 200){ // never gets here, status is always 0 from the block } } xhr.open('GET', url); xhr.responseType = 'blob'; xhr.send();
Ajax GET request of URL fails, but hurl.it GET request of same URL works. What gives?
I'm trying to access the contents of a web page as part of the functionality of a javascript Chrome extension I'm creating and have encountered a bit of a puzzle. When accessing the resource as part of an Ajax GET request in my extension's script, the resource does not correctly load. When I attempt the same GET request through hurl.it (with follow-redirects on and no header modifications), the data loads. It also works if I just enter the URL in my browser. I can't figure out what hurl.it is doing differently in its request and how to fix my own. The URL I'm trying to query is in the form of (with 'Hello' as an example search): http://overdrive.dclibrary.org/BANGSearch.dll?Type=FullText&PerPage=24&URL=SearchResults.htm&Sort=SortBy%3DRelevancy&FullTextField=All&FullTextCriteria=Hello&x=0&y=0%22 This would appear in my script like: var get_url = "http://overdrive.dclibrary.org/BANGSearch.dll?Type=FullText&PerPage=24&URL=SearchResults.htm&Sort=SortBy%3DRelevancy&FullTextField=All&FullTextCriteria=Hello&x=0&y=0" $.get(get_url,function(data){ console.log(data); }); To be clear, the above code will output HTML to the console. It just doesn't include any of the results from the search query. Thanks in advance! Edit: My extension has been given permission to access anything in the dclibrary.org domain.
There's a redirect in the response, which can break a browser. HTTP/1.1 302 Moved Temporarily works in chrome though. why is it returning a 302 response? With ASP.net/IIS sometimes unauthorized (not logged in) users are redirected with a 302 response. This is bad behavior, if login is needed, it should issue a 403, but obviously this is not the intent. Use Fiddler to debug full headers (or chrome dev tools). HTTP/1.1 302 Moved Temporarily Cache-Control: private Content-Type: text/html; charset=utf-8 Location: http://overdrive.dclibrary.org/4F2C56FC-9659-4640-9E00-9433B3CC9A7F/10/50/en/SearchResults.htm?searchid=38432201s&sortby=Relevancy Server: Microsoft-IIS/7.0 X-AspNetMvc-Version: 4.0 X-AspNet-Version: 4.0.30319 Set-Cookie: Session=4F2C56FC-9659-4640-9E00-9433B3CC9A7F|0|0|50|en; expires=Tue, 01-Jan-2030 00:00:00 GMT; path=/; HttpOnly X-Powered-By: ASP.NET Date: Fri, 06 Mar 2015 20:53:31 GMT Content-Length: 12484 Connection: keep-alive Keep-Alive: 60 Via: HTTP/1.1 proxy2444 <html><head><script type="text/javascript">window.NREUM||(NREUM={});NREUM.info = {"beacon":"bam.nr-data.net","errorBeacon":"bam.nr-data.net","licenseKey":"ad9513338b","applicationID":"2495152,2495041","transactionName":"MVBbNkcACBADUU1QWggafQ1BLwMXIV1XTUcJWVUHR04kAgxVaVhSAxpwDFEEHg==","queueTime":0,"applicationTime":61,"ttGuid":"1260BAD900521DF4","agent":"js-agent.newrelic.com/nr-593.min.js"}</script><script type="text/javascript">(window.NREUM||(NREUM={})).loader_config={xpid:"VwIAVVRbGwEEXVRTAgM="};window.NREUM||(NREUM={}),__nr_require=function(t,e,n){function r(n){if(!e[n]){var o=e[n]={exports:{}};t[n][0].call(o.exports,function(e){var o=t[n][1][e];return r(o?o:e)},o,o.exports)}return e[n].exports}if("function"==typeof __nr_require)return __nr_require;for(var o=0;o<n.length;o++)r(n[o]);return r}({QJf3ax:[function(t,e){function n(t){function e(e,n,a){t&&t(e,n,a),a||(a={});for(var c=s(e),f=c.length,u=i(a,o,r),d=0;f>d;d++)c[d].apply(u,n);return u}function a(t,e){f[t]=s(t).concat(e)}function s(t){return f[t]||[]}function c(){return n(e)}var f={};return{on:a,emit:e,create:c,listeners:s,_events:f}}function r(){return{}}var o="nr#context",i=t("gos");e.exports=n()},{gos:"7eSDFh"}],ee:[function(t,e){e.exports=t("QJf3ax")},{}],3:[function(t){function e(t){try{i.console&&console.log(t)}catch(e){}}var n,r=t("ee"),o=t(1),i={};try{n=localStorage.getItem("__nr_flags").split(","),console&&"function"==typeof console.log&&(i.console=!0,-1!==n.indexOf("dev")&&(i.dev=!0),-1!==n.indexOf("nr_dev")&&(i.nrDev=!0))}catch(a){}i.nrDev&&r.on("internal-error",function(t){e(t.stack)}),i.dev&&r.on("fn-err",function(t,n,r){e(r.stack)}),i.dev&&(e("NR AGENT IN DEVELOPMENT MODE"),e("flags: "+o(i,function(t){return t}).join(", ")))},{1:20,ee:"QJf3ax"}],4:[function(t){function e(t,e,n,i,s){try{c?c-=1:r("err",[s||new UncaughtException(t,e,n)])}catch(f){try{r("ierr",[f,(new Date).getTime(),!0])}catch(u){}}return"function"==typeof a?a.apply(this,o(arguments)):!1}function UncaughtException(t,e,n){this.message=t||"Uncaught error with no additional information",this.sourceURL=e,this.line=n}function n(t){r("err",[t,(new Date).getTime()])}var r=t("handle"),o=t(6),i=t("ee"),a=window.onerror,s=!1,c=0;t("loader").features.err=!0,t(3),window.onerror=e;try{throw new Error}catch(f){"stack"in f&&(t(4),t(5),"addEventListener"in window&&t(1),window.XMLHttpRequest&&XMLHttpRequest.prototype&&XMLHttpRequest.prototype.addEventListener&&t(2),s=!0)}i.on("fn-start",function(){s&&(c+=1)}),i.on("fn-err",function(t,e,r){s&&(this.thrown=!0,n(r))}),i.on("fn-end",function(){s&&!this.thrown&&c>0&&(c-=1)}),i.on("internal-error",function(t){r("ierr",[t,(new Date).getTime(),!0])})},{1:5,2:8,3:3,4:7,5:6,6:21,ee:"QJf3ax",handle:"D5DuLP",loader:"G9z0Bl"}],5:[function(t,e){function n(t){i.inPlace(t,["addEventListener","removeEventListener"],"-",r)}function r(t){return t[1]}var o=(t(1),t("ee").create()),i=t(2)(o),a=t("gos");if(e.exports=o,n(window),"getPrototypeOf"in Object){for(var s=document;s&&!s.hasOwnProperty("addEventListener");)s=Object.getPrototypeOf(s);s&&n(s);for(var c=XMLHttpRequest.prototype;c&&!c.hasOwnProperty("addEventListener");)c=Object.getPrototypeOf(c);c&&n(c)}else XMLHttpRequest.prototype.hasOwnProperty("addEventListener")&&n(XMLHttpRequest.prototype);o.on("addEventListener-start",function(t){if(t[1]){var e=t[1];"function"==typeof e?this.wrapped=t[1]=a(e,"nr#wrapped",function(){return i(e,"fn-",null,e.name||"anonymous")}):"function"==typeof e.handleEvent&&i.inPlace(e,["handleEvent"],"fn-")}}),o.on("removeEventListener-start",function(t){var e=this.wrapped;e&&(t[1]=e)})},{1:21,2:22,ee:"QJf3ax",gos:"7eSDFh"}],6:[function(t,e){var n=(t(2),t("ee").create()),r=t(1)(n);e.exports=n,r.inPlace(window,["requestAnimationFrame","mozRequestAnimationFrame","webkitRequestAnimationFrame","msRequestAnimationFrame"],"raf-"),n.on("raf-start",function(t){t[0]=r(t[0],"fn-")})},{1:22,2:21,ee:"QJf3ax"}],7:[function(t,e){function n(t,e,n){var r=t[0];"string"==typeof r&&(r=new Function(r)),t[0]=o(r,"fn-",null,n)}var r=(t(2),t("ee").create()),o=t(1)(r);e.exports=r,o.inPlace(window,["setTimeout","setInterval","setImmediate"],"setTimer-"),r.on("setTimer-start",n)},{1:22,2:21,ee:"QJf3ax"}],8:[function(t,e){function n(){f.inPlace(this,p,"fn-")}function r(t,e){f.inPlace(e,["onreadystatechange"],"fn-")}function o(t,e){return e}function i(t,e){for(var n in t)e[n]=t[n];return e}var a=t("ee").create(),s=t(1),c=t(2),f=c(a),u=c(s),d=window.XMLHttpRequest,p=["onload","onerror","onabort","onloadstart","onloadend","onprogress","ontimeout"];e.exports=a,window.XMLHttpRequest=function(t){var e=new d(t);try{a.emit("new-xhr",[],e),u.inPlace(e,["addEventListener","removeEventListener"],"-",function(t,e){return e}),e.addEventListener("readystatechange",n,!1)}catch(r){try{a.emit("internal-error",[r])}catch(o){}}return e},i(d,XMLHttpRequest),XMLHttpRequest.prototype=d.prototype,f.inPlace(XMLHttpRequest.prototype,["open","send"],"-xhr-",o),a.on("send-xhr-start",r),a.on("open-xhr-start",r)},{1:5,2:22,ee:"QJf3ax"}],9:[function(t){function e(t){if("string"==typeof t&&t.length)return t.length;if("object"!=typeof t)return void 0;if("undefined"!=typeof ArrayBuffer&&t instanceof ArrayBuffer&&t.byteLength)return t.byteLength;if("undefined"!=typeof Blob&&t instanceof Blob&&t.size)return t.size;if("undefined"!=typeof FormData&&t instanceof FormData)return void 0;try{return JSON.stringify(t).length}catch(e){return void 0}}function n(t){var n=this.params,r=this.metrics;if(!this.ended){this.ended=!0;for(var i=0;c>i;i++)t.removeEventListener(s[i],this.listener,!1);if(!n.aborted){if(r.duration=(new Date).getTime()-this.startTime,4===t.readyState){n.status=t.status;var a=t.responseType,f="arraybuffer"===a||"blob"===a||"json"===a?t.response:t.responseText,u=e(f);if(u&&(r.rxSize=u),this.sameOrigin){var d=t.getResponseHeader("X-NewRelic-App-Data");d&&(n.cat=d.split(", ").pop())}}else n.status=0;r.cbTime=this.cbTime,o("xhr",[n,r,this.startTime])}}}function r(t,e){var n=i(e),r=t.params;r.host=n.hostname+":"+n.port,r.pathname=n.pathname,t.sameOrigin=n.sameOrigin}if(window.XMLHttpRequest&&XMLHttpRequest.prototype&&XMLHttpRequest.prototype.addEventListener&&!/CriOS/.test(navigator.userAgent)){t("loader").features.xhr=!0;var o=t("handle"),i=t(2),a=t("ee"),s=["load","error","abort","timeout"],c=s.length,f=t(1);t(4),t(3),a.on("new-xhr",function(){this.totalCbs=0,this.called=0,this.cbTime=0,this.end=n,this.ended=!1,this.xhrGuids={}}),a.on("open-xhr-start",function(t){this.params={method:t[0]},r(this,t[1]),this.metrics={}}),a.on("open-xhr-end",function(t,e){"loader_config"in NREUM&&"xpid"in NREUM.loader_config&&this.sameOrigin&&e.setRequestHeader("X-NewRelic-ID",NREUM.loader_config.xpid)}),a.on("send-xhr-start",function(t,n){var r=this.metrics,o=t[0],i=this;if(r&&o){var f=e(o);f&&(r.txSize=f)}this.startTime=(new Date).getTime(),this.listener=function(t){try{"abort"===t.type&&(i.params.aborted=!0),("load"!==t.type||i.called===i.totalCbs&&(i.onloadCalled||"function"!=typeof n.onload))&&i.end(n)}catch(e){try{a.emit("internal-error",[e])}catch(r){}}};for(var u=0;c>u;u++)n.addEventListener(s[u],this.listener,!1)}),a.on("xhr-cb-time",function(t,e,n){this.cbTime+=t,e?this.onloadCalled=!0:this.called+=1,this.called!==this.totalCbs||!this.onloadCalled&&"function"==typeof n.onload||this.end(n)}),a.on("xhr-load-added",function(t,e){var n=""+f(t)+!!e;this.xhrGuids&&!this.xhrGuids[n]&&(this.xhrGuids[n]=!0,this.totalCbs+=1)}),a.on("xhr-load-removed",function(t,e){var n=""+f(t)+!!e;this.xhrGuids&&this.xhrGuids[n]&&(delete this.xhrGuids[n],this.totalCbs-=1)}),a.on("addEventListener-end",function(t,e){e instanceof XMLHttpRequest&&"load"===t[0]&&a.emit("xhr-load-added",[t[1],t[2]],e)}),a.on("removeEventListener-end",function(t,e){e instanceof XMLHttpRequest&&"load"===t[0]&&a.emit("xhr-load-removed",[t[1],t[2]],e)}),a.on("fn-start",function(t,e,n){e instanceof XMLHttpRequest&&("onload"===n&&(this.onload=!0),("load"===(t[0]&&t[0].type)||this.onload)&&(this.xhrCbStart=(new Date).getTime()))}),a.on("fn-end",function(t,e){this.xhrCbStart&&a.emit("xhr-cb-time",[(new Date).getTime()-this.xhrCbStart,this.onload,e],e)})}},{1:"XL7HBI",2:10,3:8,4:5,ee:"QJf3ax",handle:"D5DuLP",loader:"G9z0Bl"}],10:[function(t,e){e.exports=function(t){var e=document.createElement("a"),n=window.location,r={};e.href=t,r.port=e.port;var o=e.href.split("://");return!r.port&&o[1]&&(r.port=o[1].split("/")[0].split("#").pop().split(":")[1]),r.port&&"0"!==r.port||(r.port="https"===o[0]?"443":"80"),r.hostname=e.hostname||n.hostname,r.pathname=e.pathname,r.protocol=o[0],"/"!==r.pathname.charAt(0)&&(r.pathname="/"+r.pathname),r.sameOrigin=!e.hostname||e.hostname===document.domain&&e.port===n.port&&e.protocol===n.protocol,r}},{}],11:[function(t,e){function n(t){return function(){r(t,[(new Date).getTime()].concat(i(arguments)))}}var r=t("handle"),o=t(1),i=t(2);"undefined"==typeof window.newrelic&&(newrelic=window.NREUM);var a=["setPageViewName","addPageAction","setCustomAttribute","finished","addToTrace","inlineHit","noticeError"];o(a,function(t,e){window.NREUM[e]=n("api-"+e)}),e.exports=window.NREUM},{1:20,2:21,handle:"D5DuLP"}],gos:[function(t,e){e.exports=t("7eSDFh")},{}],"7eSDFh":[function(t,e){function n(t,e,n){if(r.call(t,e))return t[e];var o=n();if(Object.defineProperty&&Object.keys)try{return Object.defineProperty(t,e,{value:o,writable:!0,enumerable:!1}),o}catch(i){}return t[e]=o,o}var r=Object.prototype.hasOwnProperty;e.exports=n},{}],D5DuLP:[function(t,e){function n(t,e,n){return r.listeners(t).length?r.emit(t,e,n):(o[t]||(o[t]=[]),void o[t].push(e))}var r=t("ee").create(),o={};e.exports=n,n.ee=r,r.q=o},{ee:"QJf3ax"}],handle:[function(t,e){e.exports=t("D5DuLP")},{}],XL7HBI:[function(t,e){function n(t){var e=typeof t;return!t||"object"!==e&&"function"!==e?-1:t===window?0:i(t,o,function(){return r++})}var r=1,o="nr#id",i=t("gos");e.exports=n},{gos:"7eSDFh"}],id:[function(t,e){e.exports=t("XL7HBI")},{}],loader:[function(t,e){e.exports=t("G9z0Bl")},{}],G9z0Bl:[function(t,e){function n(){var t=l.info=NREUM.info;if(t&&t.licenseKey&&t.applicationID&&f&&f.body){s(h,function(e,n){e in t||(t[e]=n)}),l.proto="https"===p.split(":")[0]||t.sslForHttp?"https://":"http://",a("mark",["onload",i()]);var e=f.createElement("script");e.src=l.proto+t.agent,f.body.appendChild(e)}}function r(){"complete"===f.readyState&&o()}function o(){a("mark",["domContent",i()])}function i(){return(new Date).getTime()}var a=t("handle"),s=t(1),c=(t(2),window),f=c.document,u="addEventListener",d="attachEvent",p=(""+location).split("?")[0],h={beacon:"bam.nr-data.net",errorBeacon:"bam.nr-data.net",agent:"js-agent.newrelic.com/nr-593.min.js"},l=e.exports={offset:i(),origin:p,features:{}};f[u]?(f[u]("DOMContentLoaded",o,!1),c[u]("load",n,!1)):(f[d]("onreadystatechange",r),c[d]("onload",n)),a("mark",["firstbyte",i()])},{1:20,2:11,handle:"D5DuLP"}],20:[function(t,e){function n(t,e){var n=[],o="",i=0;for(o in t)r.call(t,o)&&(n[i]=e(o,t[o]),i+=1);return n}var r=Object.prototype.hasOwnProperty;e.exports=n},{}],21:[function(t,e){function n(t,e,n){e||(e=0),"undefined"==typeof n&&(n=t?t.length:0);for(var r=-1,o=n-e||0,i=Array(0>o?0:o);++r<o;)i[r]=t[e+r];return i}e.exports=n},{}],22:[function(t,e){function n(t){return!(t&&"function"==typeof t&&t.apply&&!t[i])}var r=t("ee"),o=t(1),i="nr#wrapper",a=Object.prototype.hasOwnProperty;e.exports=function(t){function e(t,e,r,a){function nrWrapper(){var n,i,s,f;try{i=this,n=o(arguments),s=r&&r(n,i)||{}}catch(d){u([d,"",[n,i,a],s])}c(e+"start",[n,i,a],s);try{return f=t.apply(i,n)}catch(p){throw c(e+"err",[n,i,p],s),p}finally{c(e+"end",[n,i,f],s)}}return n(t)?t:(e||(e=""),nrWrapper[i]=!0,f(t,nrWrapper),nrWrapper)}function s(t,r,o,i){o||(o="");var a,s,c,f="-"===o.charAt(0);for(c=0;c<r.length;c++)s=r[c],a=t[s],n(a)||(t[s]=e(a,f?s+o:o,i,s,t))}function c(e,n,r){try{t.emit(e,n,r)}catch(o){u([o,e,n,r])}}function f(t,e){if(Object.defineProperty&&Object.keys)try{var n=Object.keys(t);return n.forEach(function(n){Object.defineProperty(e,n,{get:function(){return t[n]},set:function(e){return t[n]=e,e}})}),e}catch(r){u([r])}for(var o in t)a.call(t,o)&&(e[o]=t[o]);return e}function u(e){try{t.emit("internal-error",e)}catch(n){}}return t||(t=r),e.inPlace=s,e.flag=i,e}},{1:21,ee:"QJf3ax"}]},{},["G9z0Bl",4,9]);</script><title>Object moved</title></head><body> <h2>Object moved to here.</h2> </body></html>