在使用子域时防止预飞行选项
Prevent preflight OPTIONS when using sub domains
给定两个子域:
web.mysite.com
和api.mysite.com
当前从web.
到api.
的任何请求都会导致飞行前选项请求。如果它没有在中国额外增加600ms的请求时间,这就不是什么大问题了。
有人告诉我,在JS中设置document.domain = 'mysite.com';
可以解决这个问题,但这根本没有帮助。
是可能的/我怎么能禁用OPTIONS请求时发送到只是一个不同的子域
使用iframe
技术解决了这个问题,这似乎是Facebook/Twitter所做的。
1)设置document.domain
为根域。url为http://site.mysite.com/
,域名设置为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)使XMLHttpRequest()
从childWindow而不是主窗口。
var xhr = new window.childWindow.XMLHttpRequest();
现在所有的请求将发送没有飞行前OPTIONS
请求。
7)使用jQuery时,您还可以在设置中设置xhr的来源:
$.ajax({
...
xhr: function() {
return new window.childWindow.XMLHttpRequest();
}
});
作为@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代码中,你现在可以像使用fetch
和XMLHttpRequest
一样使用APIfetch
和APIXMLHttpRequest
…因此,无论使用什么方法和内容类型,都不会有更多的预飞行请求!
这是一个全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);
where API_URL + '/iframe'返回这个:
<!DOCTYPE html><body><script>document.domain = 'mysite.net'</script></body></html>
- 我的单元测试选项是什么
- 如何更改bigquery API中的计费层选项
- 使用Javascript获取所选选项ID
- Selectize.js:如何对整数值的选项进行排序
- 通过js在新选项卡中有条件地打开url
- 按照选项卡索引的顺序循环一个jQuery选择
- 如何在使用selectBoxIt JQuery插件时检测选项更改
- 无法在Ionic select中预先选择最后一个选项
- 如何在选项卡上定义属性'的主窗口对象
- 为什么grunt contrib connect的中间件选项的第三个参数是未定义的
- 使用此选项选择父类内部的类
- CKeditor:更改对话框中的默认选择选项
- JQuery覆盖不更改单选选项
- 活动选项卡's源代码-获取变量s值
- 绑定时将Parsley minlength消息作为选项传递时,未对其进行自定义
- 如何从选择框中的选项中获取属性值
- 如何在从多选下拉列表中选择选项值时动态生成文本框
- Fancybox插件:重写href选项在飞行
- 在使用子域时防止预飞行选项
- CORS预飞行选项请求返回错误,但仍在发送POST