由于决定完全不受我的控制,我处于以下情况:
我在catalog.org上有产品列表
单击产品上的“添加到购物车”按钮会发出AJAX JSONP请求到secure.com/product/add/[productKey],这会将购物车记录保存到数据库,设置一个cookie使用购物车ID ,并返回真实的响应(如果失败则返回false)
回到catalog.org,如果回复为true,则向secure.com/cart/info,读取购物车ID cookie 的另一个AJAX JSONP请求,获取记录,并返回购物车中的商品数量
再次返回catalog.org,读取回复并更新页面上的元素,显示购物车中的商品数量(如果有)
此时,点击catalog.org上的“转到购物车”按钮会在secure.com上显示购物车摘要
这在Firefox 17,Chrome 32和IE 11中运行良好。它也适用于我们开发和测试环境中的IE8 - IE10,其中catalog.org是catalog.development.com和catalog.test.com以及secure.com分别是secure.development.com和secure.test.com。
然而,在我们部署到生产后,这停止了在IE8 - IE10中工作。将产品添加到购物车后,购物车中的商品数量会在catalog.org上成功更新。然后,在单击catalog.org上的“转到购物车”按钮后,secure.com上的购物车摘要显示任何内容,因为它无法读取cookie。转到缓存> IE develeoper工具中的“查看cookie信息”显示没有购物车ID cookie。它应该存在,就像在其他浏览器和我们的开发和测试环境中一样。
我相信正在发生的事情是IE阻止第三方cookie。我们已经为secure.com上的所有请求添加了一个P3P精简策略标头,但cookie仍未设置。我们设置的标题是:
P3P: CP="CAO PSA OUR"
为什么不在IE8 - IE10中添加紧凑的策略头修复此问题?如何修复此问题才能在所有版本的IE中使用?
解决方案
下面列出了一些好主意。我接受了@ sdecima's,因为它听起来最有希望。我们最终结合了其中的一些想法但设法避免了XDomainRequest:
- 点击产品上的“添加到购物车”按钮可制作AJAX JSONP 请求secure.com/product/add/[productKey],它可以保存购物车 记录到数据库,设置一个带有购物车ID 的cookie,并返回一个 真实的回应(如果失败则为假)
我们更改了secure.com/product/add上的操作,以返回一个JSON对象,其中包含指示成功或失败和购物车ID的布尔值。
- 返回catalog.org,如果响应为真,则另一个AJAX JSONP 请求secure.com/cart/info,读取购物车ID cookie ,获取记录,并返回该项中的项目数 车
我们更改了回调函数以检查响应对象中的两个属性。如果成功,并且存在购物车ID,我们会在页面上创建隐藏的iframe。 iframe的src
属性设置为我们添加到secure.com的新端点。此操作接受购物车ID参数并保存购物车ID Cookie。我们不再需要在secure.com/product/add操作中保存cookie。
接下来,我们更改了secure.com/cart/info上的操作以接受购物车ID参数。此操作将使用购物车ID参数(如果存在)来获取购物车信息,否则它仍将尝试读取cookie。如果我们可以保证iframe已经完成加载并且cookie已经保存在secure.com上,那么这个额外的检查将是不必要的,但我们无法知道iframe何时完成了对目录的加载。由于浏览器安全限制而组织。
最后,仍然需要P3P标头CP="CAO PSA OUR"
才能在IE7-IE10中工作。 (是的,这也适用于IE7:)
我们现在有一个解决方案(尽管是一个非常复杂的解决方案),用于保存和访问适用于所有主流浏览器的跨域cookie,至少在我们能够可靠测试的时候。
我们可能会对此进行一些重构。首先,此时对secure.com/cart/info的第二个AJAX JSONP请求是多余的,因为我们可以将原始请求中所需的所有信息返回到secure.com/product/add操作(更改的附带好处)返回JSON对象的操作 - 加上我们可以返回一条错误消息,指出在出现错误时它确实失败的原因。)
答案 0 :(得分:7)
Cookie不会在IE 8和9上通过跨源请求。它应该适用于IE 10和11。
在IE8 / 9上XMLHttpRequest部分支持CORS,并且在XDomainRequest object的帮助下进行跨源请求,http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx不会向每个请求发送Cookie。
您可以在以下官方MSDN博客文章中了解更多相关信息:
CORS
特别是这部分:
5。不会随请求一起发送身份验证或Cookie
为了防止滥用用户的环境权限(例如, cookie,HTTP凭证,客户端证书等),请求将 被剥夺的cookie和凭据,将忽略任何 HTTP中的身份验证质询或Set-Cookie指令 响应即可。 XDomainRequests不会在以前经过身份验证的情况下发送 连接,因为一些Windows身份验证协议(例如 NTLM / Kerberos)是基于每个连接而不是基于请求的。
从IE10开始,对XMLHTTPRequest添加了完整的http://blogs.msdn.com/b/ie/archive/2012/02/09/cors-for-xhr-in-ie10.aspx支持,它应该可以正常使用来自服务器的响应的正确的Access-Control-Allow-Origin标头属性(希望设置浏览器上的cookie。)
更多相关信息:
http://www.html5rocks.com/en/tutorials/cors/
在这里:
MSDN post
在IE8 / 9上解决此问题的唯一方法是引用与上述相同的{{3}}:
希望对跨用户执行用户身份验证的网站 请求可以使用显式方法(例如POST主体中的令牌或 URL)传递此身份验证信息而不会冒险 用户的环境权限。
答案 1 :(得分:3)
结论:第三方Cookie通常被隐私/广告拦截扩展程序阻止,应被视为不可靠。你会在脚下射击,让它继续生产。
语法表明端点有一天会变成RESTful。唯一的问题是使用cookie,它会将整个“无状态”概念抛到窗外!理想情况下,应对API进行更改。如果您没有与第三方集成(即“secure.com”由贵公司运营),这绝对是解决问题的正确方法。
将cartId
移出 secure.com Cookie进入其查询字符串:
secure.com/product/add/9876?cartId=1234 //should be a POST
从哪里获得有效的cartId
值?我们可以将其保留在目录域的某些secure-com-cart-id
cookie集中,这将避免任何跨域问题。检查该值,如果存在,则附加到每个 secure.com 请求,如上所述:
$.post('secure.com/product/add/9876', { //needs jQuery.cookie
cartId: $.cookie('secure-com-cart-id')
});
如果您没有有效的cartId
,请将其视为新用户,并在没有参数的情况下发出请求。然后,您的API应分配一个新ID并在响应中返回它。然后可以更新“本地”secure-com-cart-id
cookie。冲洗并重复。
Voila,您只是坚持使用活跃的用户购物车,而不会使用Cookie污染API调用。对你的建筑师大喊大叫。如果您不能这样做(更改API语法或大喊大叫),则必须设置到 secure.com 端点的隧道,这样就不会有跨域请求 - 基本上就是坐着在 catalog.org/secure-com-endpoint ,它会将请求逐字地传递给 secure.com 。这是一种专门用于避免对API进行更改的解决方法,只是不要使用代码并设置适当的Apache / IIS / F5规则来代替它。快速搜索出现了几个解释,this one对我来说非常好。
P.S。:我认为这是a classic XY problem。解决方案不一定是关于持久化第三方cookie,而是将必要参数传递给第三方,同时将数据保存在某处。
答案 2 :(得分:0)
虽然正确的解决方案是改变架构,但如果您正在寻找快速,临时的解决方案:
JSONP文件实际上只是javascript。您可以添加一行代码以将Cookie设置到JSONP的前面。
例如,而不是:
callback({"exampleKey": "exampleValue"});
您的JSONP可能如下:
document.cookie="cartID=1234";
callback({"exampleKey": "exampleValue"});
答案 3 :(得分:0)
如果您控制DNS记录,请创建一个新条目,以便两个服务器位于同一个域中。
答案 4 :(得分:0)
是否有1个数据库服务于catalog.org和secure.com,还是可以进行通信?
如果是这样的话,你就明白了。
当catalog.org服务器cookie时,将其保存在db中。 当secure.com服务器cookie时,将其保存在db中。 然后,您可以确定哪个购物车属于哪个用户。
当用户访问catalog.org时:
检查他是否有cat_org cookie,如果没有,则:
:
现在db可以将cat_cookie_id映射到secure_cookie_id,反之亦然。