0

(注意:这是我的问题Can jQuery.getJSON put a domain's cookies in the header it make?并涵盖在 AJAX 请求中设置 cookie 的 XSS 案例?

有人告诉我,我无法使用$.cookie(..., ..., {domain: ...}). 但是在对我最后一个问题的回复中,@zanlok 说“但是,服务器的回复肯定可以设置一个 cookie”,并且得到了两个支持。

所以我想我会尝试使用一种服务,该服务是为设置 cookie 的明确目的而创建的,称为Freebase 的“触摸”API。调用看起来像:

$.getJSON("http://api.sandbox-freebase.com/api/service/touch",
{}, // URL parameters
afterCookieIsSetCallback); // Callback function

在 FireBug 中查看响应标头是这样的:

Date    Wed, 24 Nov 2010 03:35:28 GMT
Server  Apache
X-Metaweb-Cost  [...]
Etag    [...]
Expires Wed, 24 Nov 2010 03:35:29 GMT
Cache-Control   no-store
Vary    Accept-Encoding
Content-Encoding    gzip
Set-Cookie  mwLastWriteTime=1290569730|10325_9202a8c04000641f80000000199eff96|sandbox; expires=Thu, 25-Nov-2010 03:35:28 GMT; Path=/
Last-Modified   Wed, 24 Nov 2010 03:35:28 GMT
Content-Length  134
Content-Type    text/plain; charset=utf-8
X-Cache MISS from cache01.sandbox.sjc1.metaweb.com
Connection  keep-alive
X-Metaweb-TID   cache;cache01.sandbox.sjc1:8101;2010-11-24T03:35:28Z;0001

所以那里肯定有一个 Set-Cookie,脚本运行响应处理程序。然而,该脚本发出的后续 JSON 请求的请求标头中不存在 cookie .sandbox-freebase.com

(相比之下,只需在地址栏中输入 touch api URL 并以这种方式加载它确实会为将来的请求设置 cookie。即使在其他选项卡中也适用。)

这似乎与之前的“预期行为”有所偏差,因为 MetaWeb 大约在“2007-2009”发布了一个工具包,似乎认为这种方法可以工作:

http://www.google.com/codesearch/p?hl=en#v099O4eZ5cA/trunk/src/freebase/api.js&q=touch%20package:http://mjt%5C.googlecode%5C.com&l=340

在不太了解它的情况下,我想知道这是否是 Firefox 采用的最近更改,然后 WebKit 也效仿了。也许这里提到的那个:

http://trac.webkit.org/browser/trunk/WebCore/xml/XMLHttpRequest.cpp#L856

那么有没有关于这个特定问题的规范文档?

4

2 回答 2

4

您正在进行的 AJAX 调用正在向顶级 url(地址栏中的 url)域之外的域发出请求。这导致它成为第 3 方 cookie,默认情况下 Internet Explorer 不会保留第 3 方 cookie。这意味着 cookie 将在第一个请求的 Set-Cookie 标头中返回,但您对该服务器发出的后续请求不会在请求中发送该 cookie。

就像您说的,如果您直接访问浏览器中的 url,它就可以工作。这是因为在这种情况下,它是第一方 cookie。

为了让 IE 接受第 3 方 cookie,SET-COOKIE在其响应中发送标头的服务器还必须设置 P3P 策略标头。

这是一个示例,当您导航到 CNN 时,您会注意到它发出的一个请求是对 b.scorecardresearch.com 的域名的请求,scorecardresearch 正在丢弃一个跟踪 cookie,但这个 cookie 被认为是第 3 方 cookie。因此,为了使其正常工作,他们还必须包含一个p3p标题,请参见下面的标题:

HTTP/1.1 200 OK
Content-Length: 43
Content-Type: image/gif
Date: Thu, 02 Dec 2010 19:57:16 GMT
Connection: keep-alive
Set-Cookie: UID=133a68a4-63.217.184.91-1288107038; expires=Sat, 01-Dec-2012 19:57:16 GMT; path=/; domain=.scorecardresearch.com
P3P: policyref="/w3c/p3p.xml", CP="NOI DSP COR NID OUR IND COM STA OTC"
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Pragma: no-cache
Cache-Control: private, no-cache, no-cache=Set-Cookie, no-store, proxy-revalidate
Server: CS

如果您要复制此标头并将其添加到响应中,您会注意到 cookie 开始工作,

P3P: policyref="/w3c/p3p.xml", CP="NOI DSP COR NID OUR IND COM STA OTC"

最好为您的业务制作一个特定的 P3P 标头,但以上内容应适用于测试目的。

于 2010-12-02T20:02:31.740 回答
1

如果我正确理解你,你想知道为什么服务器Set-Cookie只在第一个请求时发送。如果这是真的,那么这是设计使然 - 看看这里:

Set-Cookie就像一个设置器 - 服务器将它发送给浏览器以在本地缓存它。每次都可以发送,但没有必要这样做,所以只有在需要更改本地存储的值时才会再次发送。

另一方面,浏览器Cookie每次都会发送标头,其中Set-Cookie包含服务器最后一次发出的内容。

于 2010-11-24T04:34:55.287 回答