15

给定两个子域:

web.mysite.comapi.mysite.com

web.当前从to发出任何请求都会api.导致发出预检 OPTIONS 请求。如果它不在中国的请求中增加额外的 600 毫秒,这将不是什么大问题。

有人告诉我,document.domain = 'mysite.com';在 JS 中设置可以解决问题,但这根本没有帮助。

发送到不同的子域时是否有可能/如何禁用 OPTIONS 请求。

4

3 回答 3

14

iframe使用似乎是 Facebook / Twitter 所做的技术解决了这个问题。

以下步骤:

1)将 设置document.domain为根域。所以给定 urlhttp://site.mysite.com/我在 JavaScript 中设置域document.domain = 'mysite.com';

2)设置从 API 域中提取 HTML 文件的 iframe。

<iframe id="receiver" src="http://api.mysite.com/receiver" style="position:absolute;left:-9999px"></iframe>

这被设置为无法看到。

3)设置接收者页面的HTML设置域:

<!DOCTYPE html><body><script>document.domain='mysite.com'</script></body></html>

4)向 iframe添加了一个onload事件,以便在加载后捕获窗口。

onload="window.tempIframeCallback()"

5)将子窗口分配给一个变量。

window.tempIframeCallback = function() {
  window.childWindow = window.receiver.contentWindow;
}

6)从childWindowXMLHttpRequest()而不是主窗口制作。

var xhr = new window.childWindow.XMLHttpRequest();

现在所有请求都将在没有预检OPTIONS请求的情况下发送。


7)使用jQuery时,也可以在设置中设置xhr的来源:

$.ajax({
  ...
  xhr: function() {
    return new window.childWindow.XMLHttpRequest();
  }
});
于 2015-07-22T06:16:26.113 回答
6

作为对@Phill 值得所有功劳的回答的补充,这里是最终的 html 代码,它也公开了 iframe 的fetch功能:

<!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>

当然,HTML“ http://api.mysite.com/receiver ”应该检索:

<!DOCTYPE html>
<html><body><script>
    document.domain='mysite.com';
</script></body></html>

然后,在你的 JS 代码中,你现在可以像你一样使用APIfetch和......等等,无论使用什么方法和内容类型,都不再需要预检请求!APIXMLHttpRequestfetchXMLHttpRequest

于 2016-08-11T02:07:59.127 回答
2

这是一个全 javascript 方法:

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);

其中 API_URL + '/iframe' 返回:

<!DOCTYPE html><body><script>document.domain = 'mysite.net'</script></body></html>
于 2017-01-23T01:01:35.197 回答