-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Use XHR + POST for request if CORS supported #420
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
/*global XDomainRequest:false*/ | ||
'use strict'; | ||
|
||
// First, check for JSON support | ||
|
@@ -105,7 +106,9 @@ var Raven = { | |
(uri.port ? ':' + uri.port : '') + | ||
'/' + path + 'api/' + globalProject + '/store/'; | ||
|
||
if (uri.protocol) { | ||
// can safely use protocol relative (//) if target host is | ||
// app.getsentry.com; otherwise use protocol from DSN | ||
if (uri.protocol && uri.host !== 'app.getsentry.com') { | ||
globalServer = uri.protocol + ':' + globalServer; | ||
} | ||
|
||
|
@@ -840,7 +843,7 @@ function send(data) { | |
}); | ||
} | ||
|
||
function makeRequest(opts) { | ||
function makeImageRequest(opts) { | ||
// Tack on sentry_data to auth options, which get urlencoded | ||
opts.auth.sentry_data = JSON.stringify(opts.data); | ||
|
||
|
@@ -856,6 +859,47 @@ function makeRequest(opts) { | |
img.src = src; | ||
} | ||
|
||
function makeXhrRequest(opts) { | ||
var request; | ||
|
||
function handler() { | ||
if (request.status === 200) { | ||
if (opts.onSuccess) { | ||
opts.onSuccess(); | ||
} | ||
} else if (opts.onError) { | ||
opts.onError(); | ||
} | ||
} | ||
|
||
request = new XMLHttpRequest(); | ||
if ('withCredentials' in request) { | ||
request.onreadystatechange = function () { | ||
if (request.readyState !== 4) { | ||
return; | ||
} | ||
handler(); | ||
}; | ||
} else { | ||
request = new XDomainRequest(); | ||
// onreadystatechange not supported by XDomainRequest | ||
request.onload = handler; | ||
} | ||
|
||
// NOTE: auth is intentionally sent as part of query string (NOT as custom | ||
// HTTP header) so as to avoid preflight CORS requests | ||
request.open('POST', opts.url + '?' + urlencode(opts.auth)); | ||
request.send(JSON.stringify(opts.data)); | ||
} | ||
|
||
function makeRequest(opts) { | ||
var hasCORS = | ||
'withCredentials' in new XMLHttpRequest() || | ||
typeof XDomainRequest !== 'undefined'; | ||
|
||
return (hasCORS ? makeXhrRequest : makeImageRequest)(opts); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm just going to assume that this is going to be problematic to fall back to the image request, because the goal of XHR is to be able to transmit more data. And if we attempt to fall back, it's unlikely things are even going to work. So I guess we need to make a decision here: do we just 100% remove the image transport, and assume if there's no CORS support, maybe we just ignore entirely? /cc @dcramer There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems to have worked well so far? Or is the plan to increase the amount of data going forward? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, we want to start sending more. Or at least, not be so paranoid about it. See: #419 as one thing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd rather we got notified of an issue, even with partial information due to data constraints, rather than have it disappear into the ether. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One idea: we could deploy the fallback, see if we get any actual hits from it, to assess its usefulness. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree. So we'll have to implement the stuff to make sure we trim our data packet before sending to make an attempt. Otherwise, we'll just get a 413 on the response and Sentry won't log it anyways. So not sure the best solution here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Let's do that when we increase the stack size – not here. |
||
} | ||
|
||
// Note: this is shitty, but I can't figure out how to get | ||
// sinon to stub document.createElement without breaking everything | ||
// so this wrapper is just so I can stub it for tests. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not an expert here, so lemme get this straight:
XMLHttpRequest
that has the proper support. IsXMLHttpRequest
guaranteed to exist? I assume if it's undefined, we'll have an issue callingnew XMLHttpRequest()
XDomainRequest
, which is IE specific. This is great, but then insidemakeXhrRequest
,XDomainRequest
isn't used or even attempted to be used. So it's not clear to me what good this check is doing.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Realistically – yes, unless someone has removed it (e.g. the host page or a browser extension).
But I'll add the check.
Yep, that was a mistake.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about the IE case though since they use XDomainRequest? Or do I misunderstand this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The XMLHttpRequest object still exists, and can be safely queried for presence of
withCredentials
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, ok. I see. IE's
XMLHttpRequest
object just isn't capable of issuing a CORS request.