通过修改 HTTP 标头使用没有 CORS 的 XMLHttpRequest?

Posted

技术标签:

【中文标题】通过修改 HTTP 标头使用没有 CORS 的 XMLHttpRequest?【英文标题】:Using XMLHttpRequest without CORS by modifying HTTP headers? 【发布时间】:2013-01-18 00:25:19 【问题描述】:

我正在使用(已弃用的)Twitter API 1.0 进行一些测试

例如,我想从 API 获取数据,客户端使用来自任何跨域网页的 AJAX 浏览器请求。它可以是新的空白选项卡、本地 html 页面或任何现有网站。

我尝试过 JSONP,效果很好,但我想使用默认的 XMLHttpRequest,即使 Twitter 服务器不支持 CORS http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing。

例如,在 google.com 主页上,我创建了一个对 Twitter API 的简单 AJAX 调用,并使用 Firebug 执行:

var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.twitter.com/1/friends/ids.json?screen_name=baptx", false);
xhr.send();

由于相同的来源策略,这将不起作用并在 Firebug 上打印错误:

Error: Failure
xhr.send();

它返回一个 HTTP 200 OK 代码,但没有从服务器接收到 JSON 数据。

我发现来自 google.com 网页的请求和来自 api.twitter 网页的请求之间有两个不同之处(它们适用于 Twitter API 请求,因为它是 API 域名,来源相同)。

添加了一个带有当前域名的 Origin HTTP 标头:

Origin  https://www.google.com

Referer HTTP 标头不是 https://api.twitter.com/ 像来自 api.twitter.com 页面的请求,但在我的情况下:

Referer https://www.google.com/webhp?hl=en

这就是为什么我试图删除 Origin HTTP 标头并将当前的 Referer HTTP 标头修改为https://api.twitter.com/

我已经使用 Firefox ModifyHeaders 扩展完成了这项工作,它可以正常工作,我可以在 Firebug 的“Net”选项卡中检查这些更改是否正确。

现在,我从来自 google.com 网页和 api.twitter.com 网页的请求中获得了相同的请求标头。 它仍然无法从 API 以外的其他域发出 AJAX 请求,即使 HTTP 标头被覆盖,为什么?

顺便问一下,您知道为什么从 Firefox“新标签”向 Twitter API 发出 AJAX 请求会起作用吗?

【问题讨论】:

不是服务器需要遵守 SOP,但浏览器需要。即使你发送不同的 header,你的浏览器也知道这是一个跨域请求。 @Bergi 很高兴知道,所以问题可能来自浏览器...... Firefox 是开源的,如果它不是跨域请求,难道不能表现得像吗?我应该更改响应 HTTP 标头而不是请求标头吗? 是的,你可以试试(我不知道扩展名)。也许还有一个隐藏的配置标志可以完全禁用 SOP。 @Bergi 感谢您的想法,实际上有方法可以禁用 SOP,但不是通过我使用的插件 相关:***.com/questions/10665108/…***.com/questions/7995223/… 【参考方案1】:

如果web服务器不允许跨域资源共享,我们必须手动添加HTTP响应头Access-Control-Allow-Origin: *

我认为问题出在请求标头中。没有 Firefox 插件来修改 HTTP 响应标头,ModifyHeaders 或 TamperData 仅支持请求标头: Modifying HTTP response headers in Firefox

我的问题其实和这个类似:Can I disable SOP (Same Origin Policy) on any browser for development?

解决方案:有人开发了一个 Firefox 插件来强制 CORS:https://addons.mozilla.org/en-US/firefox/addon/forcecors/。 或者我们可以在 GreaseMonkey 脚本中使用 GM_xmlhttpRequest,它会绕过 XMLHttpRequest 的同源策略。 还有一个名为 Header Editor 的新插件,它是开源的,可以编辑请求和响应头:https://addons.mozilla.org/en-US/firefox/addon/header-editor/。

在 Chrome 中,没有插件可以修改 HTTP 请求/响应标头,因为浏览器不提供 API,但有一个标志可以禁用 SOP (--disable-web-security)

【讨论】:

感谢您详细说明可能的解决方法。至少有一种方法可以通过 POSTMAN 在 Chrome 中执行此操作,但我不确定来自该扩展程序的请求如何设法绕过 Chrome 的标头要求。 @ray Chrome 扩展不受 cors 影响

以上是关于通过修改 HTTP 标头使用没有 CORS 的 XMLHttpRequest?的主要内容,如果未能解决你的问题,请参考以下文章

被 CORS 策略阻止:对预检的响应...没有 HTTP ok 状态。标头没有解决问题

使用cors包和设置Access-Control标头都没有运气

AngularJS 应用程序的 CORS GET 中未发送 HTTP 标头

Cors 标头未正确处理(http 请求很好,但 socke.io 连接不正确)

没有将 Cors 标头添加到响应中

Webpack 配置以使用没有 CORS 标头的 API