通过修改HTTP头来使用XMLHttpRequest避免CORS问题?

6

我正在测试(已弃用的)Twitter API 1.0。

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

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

例如,在google.com首页上,我创建了一个简单的AJAX调用Twitter API,并在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网页(它是API域名,同源)发出的请求之间存在两个区别。
已添加一个带有当前域名的Origin HTTP标头:
Origin  https://www.google.com

Referer HTTP头不像从api.twitter.com页面发出的请求https://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网页发出的请求具有相同的请求标头。 即使HTTP标头被覆盖,仍将无法从与API不同的域执行AJAX请求,为什么?
顺便问一下,您知道为什么从Firefox“新标签页”对Twitter API进行的AJAX请求会起作用吗?

2
不是服务器需要遵守 SOP,而是浏览器需要遵守。即使您发送不同的标头,您的浏览器也知道这是一个跨域请求。 - Bergi
@Bergi 很好知道,所以问题可能来自浏览器... Firefox 是开源的,难道不能像不是跨域请求一样行事吗?我应该改变响应 HTTP 标头而不是请求标头吗? - baptx
是的,你可以尝试一下(我不知道扩展名)。也许还有一个隐藏的配置标志可以完全禁用SOP。 - Bergi
@Bergi,感谢您的想法,实际上有方法可以禁用SOP,但不能通过我使用的插件来实现。 - baptx
相关链接: https://dev59.com/jWTVa4cB1Zd3GeqP_AVA https://dev59.com/zGsz5IYBdhLWcg3wTl0T - baptx
1个回答

7
如果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)。

感谢您详细介绍可能的解决方法。至少在 Chrome 中,可以通过 POSTMAN 的方式来完成,但我不确定该扩展程序是如何绕过 Chrome 的头部要求来管理请求的。 - ray
@ray Chrome扩展程序不受CORS影响。 - raythurnevoid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接