使用子域

时间:2015-07-17 04:03:29

标签: javascript ajax cors

给出两个子域:

web.mysite.comapi.mysite.com

目前,web.api.发出的任何请求都会导致预检OPTIONS请求。如果它在中国的请求中没有额外增加600毫秒,那么这不会成为一个问题。

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

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

3 个答案:

答案 0 :(得分:10)

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

以下步骤:

1)document.domain设置为根域。因此,在网址http://site.mysite.com/的情况下,我在JavaScript中设置了域document.domain = 'mysite.com';

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

<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)从childWindow而不是主窗口创建XMLHttpRequest()

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

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

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

$.ajax({
  ...
  xhr: function() {
    return new window.childWindow.XMLHttpRequest();
  }
});

答案 1 :(得分:4)

作为@ 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代码中,您现在可以使用APIfetchAPIXMLHttpRequest,就像您使用fetchXMLHttpRequest ...etvoilà一样,不再预检请求无论使用何种方法和内容类型!

答案 2 :(得分: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>