问题
Given two sub domains:
web.mysite.com
and api.mysite.com
Currently making any request from web.
to api.
results in the preflight OPTIONS request being made. This wouldn't be so much of an issue if it didn't add an extra 600ms to requests in China.
I was told that setting document.domain = 'mysite.com';
in JS would resolve the issue but this hasn't helped at all.
Is it possible / how can I disable the OPTIONS request when sending to just a different sub domain.
回答1:
Solved this using the iframe
technique which seems to be what Facebook / Twitter do.
Steps below:
1) Set the document.domain
to be the root domain. So given the url http://site.mysite.com/
I set the domain in JavaScript like document.domain = 'mysite.com';
2) Setup an iframe which pulls a HTML file from the API Domain.
<iframe id="receiver" src="http://api.mysite.com/receiver" style="position:absolute;left:-9999px"></iframe>
This is set to be positioned so it can't be seen.
3) Set the HTML of the receiver page to set the domain:
<!DOCTYPE html><body><script>document.domain='mysite.com'</script></body></html>
4) Added an onload
event to the iframe to capture the window once its loaded.
onload="window.tempIframeCallback()"
5) Assign the child window to a variable.
window.tempIframeCallback = function() {
window.childWindow = window.receiver.contentWindow;
}
6) Make the XMLHttpRequest()
from the childWindow instead of the main window.
var xhr = new window.childWindow.XMLHttpRequest();
Now all requests will be sent without a preflight OPTIONS
request.
7) When using jQuery, you can also set the source of xhr in the settings:
$.ajax({
...
xhr: function() {
return new window.childWindow.XMLHttpRequest();
}
});
回答2:
As a complement to @Phill's answer that deserves all the credits, here is the final html code, that also exposes the iframe's fetch
function:
<!DOCTYPE html>
<html><body>
<script>
document.domain = 'mysite.com';
window.setupAPI = function() {
var receiverWindow = window.receiver.contentWindow;
// you may also want to replace window.fetch here
window.APIfetch = receiverWindow.fetch;
// same thing, you may as well replace window.XMLHttpRequest
window.APIXMLHttpRequest = receiverWindow.XMLHttpRequest;
}
</script>
<iframe id="receiver"
src="http://api.mysite.com/receiver"
style="position:absolute;left:-9999px"
onload="window.setupAPI()"></iframe>
</body></html>
And of course the HTML "http://api.mysite.com/receiver" should retrieve:
<!DOCTYPE html>
<html><body><script>
document.domain='mysite.com';
</script></body></html>
And then, within your JS code, you can now use APIfetch
and APIXMLHttpRequest
like you'd use fetch
and XMLHttpRequest
... et voilà, no more preflight request whatever the method and content type used!
回答3:
Here's an all javascript approach:
document.domain = 'mysite.net';
var apiIframe = document.createElement('iframe');
apiIframe.onload = function(){
window.XMLHttpRequest = this.contentWindow.XMLHttpRequest;
};
apiIframe.setAttribute('src', API_URL + '/iframe');
apiIframe.style.display = 'none';
document.body.appendChild(apiIframe);
where API_URL + '/iframe' returns this:
<!DOCTYPE html><body><script>document.domain = 'mysite.net'</script></body></html>
来源:https://stackoverflow.com/questions/31468214/prevent-preflight-options-when-using-sub-domains