使用XMLHTTPRequest发送cookie (TVMLJS)

17
我正在开发一个适用于我的AppleTV的应用程序。该应用程序将从一个未为此类事情开发任何API的在线网站读取电影。
我使用XMLHTTPRequest来获取不同的URL,并让用户搜索他的电影等...一切都工作得很好,除了一个请求。为了获取电影URL,我必须向特定地址发送一个get请求(假设http://example.com/getmovie.html),并带有一个恒定的cookie(假设mycookie=cookie)。
我尝试使用setRequestHeader:
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.withCredentials = true;
xhr.setRequestHeader('Cookie', 'mycookie=cookie');
xhr.send();

但是似乎没有发送任何cookie。我也尝试使用Document.cookie设置cookie,就像我在“正常”的js脚本(在我的浏览器中运行)中可能会做的那样,但仍然没有成功。这非常令人沮丧,特别是因为我离我的应用程序结束如此之近。我猜跨域可能是问题所在,但如果我不必设置cookie,我就能够毫无问题地获取URL,所以我有点迷失方向。请告诉我如何使用特定的cookie头获取http://example.com/getmovie.html。感谢您的帮助。

很抱歉告诉您,由于安全原因,JavaScript的xmlHTTPRequest函数不允许设置Cookie标头,如此所示:https://dev59.com/t2Up5IYBdhLWcg3wj4Hu。我认为您能够进行get请求的最好方式是使用您自己运行的代理服务器。 - Mohammad Ali
谢谢。还有其他方法可以使用cookie执行对URL的get请求吗?也许可以使用xmlHTTPRequest以外的东西?这种安全措施似乎有点过头了... 从我在其他帖子上看到的内容来看,我认为安全性是来自浏览器的。但在我的情况下,没有浏览器,因为它是一个AppleTV应用程序。 - Scaum
这可能是 XMLHttpRequest 规范的一部分,如果您对发送请求的服务器具有控制权,并且能够修改响应标头,则可能可以使用 Cookie 进行 XMLHttpRequest 请求。 - Mohammad Ali
很遗憾,我无法对我发送请求的服务器进行控制... 我觉得很奇怪,Javascript无法发送cookie,特别是在浏览器中发送伪造cookie非常容易(检查元素/网络/修改并重新发送请求/添加你的cookie)。如果发送任意cookie真的是安全问题,那么这将是不可能的(或者整个互联网现在都会有一个巨大的问题^^),所以如果没有解决我的问题,我会感到非常惊讶。谢谢您抽出时间回答我的问题 :) - Scaum
没有问题,但我认为禁止使用 JavaScript 发送 cookie 的原因并不是防止你在自己控制的机器上发送伪造的 cookie,而是防止你在自己的网站上放置能够让你在其他人的机器上设置不属于你所拥有域名的 cookie 的 JavaScript。例如,假设你运行一个博客,在每个页面背后都会向竞争对手的博客发出含有错误会话 cookie 的 xmlhttprequest,这实际上会使人们注销竞争对手的网站。如果可能的话,我可以写一个回答来获取积分吗? - Mohammad Ali
显示剩余2条评论
5个回答

14

很抱歉告诉您,由于安全原因,JavaScript的xmlHTTPRequest函数不允许设置cookie头,如此所示:为什么使用setRequestHeader时无法设置cookie和set-cookie头? 我认为最好的方式是通过您运行的代理服务器进行get请求。我相信它是这样构建的,以防止您在不拥有的域上设置cookie,此外,在我查看的文档中没有提到cookie的持久性或管理,因此我认为这个问题没有其他解决方案。


6

问题在于这一行代码:xhr.setRequestHeader('Cookie', 'mycookie=cookie');,因为'Cookie'头部是保留给客户端浏览器发送存储的cookie的。这意味着你试图做浏览器已经在做的事情。当你发送任何请求时,客户端浏览器会自动获取与你请求的站点相关的所有cookie,并将它们放在“Cookie”头部中,你不需要做任何其他操作,如果你的cookie存在于浏览器中,它就会被发送。


您错了,XMLHttpRequest 不会将与请求站点相关的 cookies 放入 Cookie 标头中。至少这不是默认行为。 - mangusta
3
我并没有说XMLHttpRequest会自行添加Cookie头,而是浏览器会这样做:https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Creating_cookies - asceta
浏览器也不会这样做。如果它这样做将是一种安全漏洞。我建议删除您的答案,因为它具有误导性和错误性。 - mangusta
4
抱歉,@mangusta,您的说法是错误的。问题中明确设置了withCredentials,这将启用cookie(和授权标头),无论访问哪个站点。对于同站点,始终会设置cookie。对于其他域,您需要在XHR对象上将withCredentials设置为true(以及在服务器端处理CORS)。 - DennisK

5
如果有人遇到同样的问题:
我并没有找到在javascript中发送cookie的解决方案。然而,在我的情况下,请求的来源并不重要,只有cookie很重要。因此,我的解决方法是创建一个PHP文件,将目标URL和cookie内容作为参数接收,然后使用cookie作为请求头发送get请求。(关于如何实现这一点的更多信息,请参阅此处:PHP GET Request,发送headers)。
在我的javascript中,我使用XMLHttpRequest连接到我的在线托管的PHP文件,并用简单的get参数接收来自PHP的响应。当然,如果请求的来源很重要,那么这个技巧就行不通了(除非您在家里托管您的文件,但在我的情况下,即使我的WAMP关闭,我也希望我的应用程序能够正常工作)。

3

Cordova如何使用XMLhttprequest发送会话cookie并允许凭据:

// JS
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/ajax.php', true);
xhr.withCredentials = true;
xhr.onreadystatechange = function() {
    if(xhr.readyState == 4 && xhr.status == 200) {
        // alert(xhr.responseText);
        // Get header from php server request if you want for something
        var cookie = xhr.getResponseHeader("Cookie");
        // alert("Cookie: " + cookie);
    }
}
xhr.send();

// Php 
// You can add cookie to header and get with (session works without it) 
header('Cookie: PHPSESSID='.$_COOKIE['PHPSESSID']);
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, X-Request-With, Set-Cookie, Cookie, Bearer');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400');

1
可以通过添加 xhr.withCredentials = true; 来解决。

当客户端浏览器已经具有cookie,并且意图是让xhr将cookie作为请求的一部分包含进去时,这个方法是有效的。 - undefined

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