为什么使用setRequestHeader进行xmlhttprequest时,无法设置cookie和set-cookie头?

我想知道为什么不能使用setRequestHeader设置cookie头。 是否有任何特定的原因,或只是他们被浏览器本身添加,所以这些头被禁用? 有没有安全问题?

– 编辑

我正在使用node.js并使用xmlhttprequest模块。 以下是testing代码:

 var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.withCredentials = true; xhr.setRequestHeader('Cookie', "key=value"); xhr.send(null); 

在这里,我需要设置Cookie标头为node.js' xmlhttprequest不显式添加cookie标头(如浏览器一样)。 当试图这样做, xmlhttprequest给出错误“ Refused to set unsafe header ”。

虽然我find了一个补丁并成功地发送了cookie头文件。 但想知道为什么它被禁用设置Cookie标头? 在我读过的地方,发现它是数据完整性和安全性所必需的,但在这种情况下可以违反什么安全性,在哪里没有提及。 我想评估这个数据完整性问题是否适用于node.js应用程序,以及如果我使用我的补丁。

我相信你会通过工作草案 ,发现

上面的头文件由用户代理控制,让它控制传输的这些方面。

首先我们需要了解的是,这些标准是作为不同浏览器之间的function互操作性的指南。 这不是浏览器的要求,因此浏览器出于不同的原因确实有不同程度的遵守这个标准。

其次,从技术上说,你可以模仿一个用户代理,把你的程序当作浏览器,并且可以很好地按照上述标准设置这些值。

最后,不允许覆盖头文件或为Content-LengthCookie等特定字段设置头文件的意图是secure design approach 。 这是劝阻或至less试图阻止HTTP请求走私 。

您可以禁用此行为:

 var xhr = new XMLHttpRequest(); xhr.setDisableHeaderCheck(true); xhr.open(...); ... 

众所周知,对浏览器来说,cookie(除其他属性)需要仔细pipe理,以防止第三方窃取用户会话(或其他数据)。 这是浏览器的问题,以及访问运行任意Javascript的网站的不受控制的性质。

当然,执行任意代码的风险对于node.js来说可能是低风险或者是无风险的,因为你只运行一个脚本,你可以运行你计划的其他代码。

如果你看看driverdan的XMLHttpRequest.js的源代码,你会发现:

  // These headers are not user setable. // The following are allowed but banned in the spec: // * user-agent var forbiddenRequestHeaders = [ "accept-charset", "accept-encoding", "access-control-request-headers", "access-control-request-method", "connection", "content-length", "content-transfer-encoding", "cookie", "cookie2", "date", "expect", "host", "keep-alive", "origin", "referer", "te", "trailer", "transfer-encoding", "upgrade", "via" ]; 

这个答案是为什么限制特别适用于node.js的脚本的具体问题 – 编码器遵循规范(尽可能接近),尽pipe感觉它可能不是node.js中必需的安全预防措施。 不过,这个默认安全级别很容易修改。

正如robertklep指出的那样,你可以使用setDisableHeaderCheck方法来禁用这个默认的预防措施。 是的,最后一点是回答你的问题或为你的问题作出重大贡献,因为在你的问题中你说:

 I have found a patch and successfully able to send the cookie-header 

现在我们发现你并不需要这个补丁。

祝你好运!

是的,这是数据完整性和安全性所必需的。 要理解这一点,你必须了解cookie在HTTP请求方法中的作用。

Cookie在识别用户,浏览器,连接等方面非常重要,并存储在networking浏览器中。 JavaScript允许您操作Cookie,但不是浏览器上的所有Cookie。 看到HTTP cookie ,这些只是由浏览器设置,以便用户不能误用(通过JavaScript)。

在受支持的浏览器上,仅在传输HTTP(或HTTPS)请求时才会使用HttpOnly会话cookie,从而限制其他非HTTP API(如JavaScript)的访问。

当你发送xmlhttprequest它读取HttpOnly cookies并通过Cookie头发送到服务器。 现在,如果你做xhr.setRequestHeader('Cookie', "key=value"); ,你试图篡改发送到服务器的cookie。 setRequestHeader会添加额外的key=value ,这可能会危害发送的cookie的完整性。

这些由服务器用来validation用户(会话,电子邮件帐户或任何帐户)。 这基本上允许服务器防止滥用cookie访问服务器。

文档提到这是为了保护数据的完整性。 http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader%28%29-method

上面的头文件由用户代理控制,让它控制传输的这些方面。 这在一定程度上保证了数据完整性。 以Sec-开头的标题名称不允许设置为允许新的头文件保证不会来自XMLHttpRequest。

我能够使用以下Gist来解决这个问题:
https://gist.github.com/killmenot/9976859

原来的想法是从这里采取的:
https://gist.github.com/jfromaniello/4087861

我面临几个问题:

  1. Gist已经过时了,不适合我。 例如“请求”lib API已更改。
  2. 我可能会使用socket.io-client的“xmlhttprequest”库,不要与socket.io-client安装在同一层。
  3. 原始的“socket.io-client”(0.9.16)使用不支持“setDisableHeaderCheck”方法(但是1.6.0)的“xmlhttprequest”(1.4.2)。 所以,我做了一个分支并使用它https://github.com/intspirit/socket.io-client/tree/0.9.16+20140408120400

socket.io-client(1.0.0-pre)使用使用正确版本的xmlhttprequest的engine.io-client。 我想在将来我会使用1.0.0版本,而不是我的叉子,指定“xhr轮询”运输和模拟XMLHttpRequest作为原始的要点。