Javascript IE8-IE10跨域JSONP cookie

Javascript IE8-IE10跨域JSONP cookie,javascript,ajax,cookies,jsonp,p3p,Javascript,Ajax,Cookies,Jsonp,P3p,由于完全超出我控制范围的决定,我处于以下情况: 我在catalog.org上有一个产品清单 单击产品上的“添加到购物车”按钮会向secure.com/product/Add/[productKey]发出一个AJAX JSONP请求,该请求将购物车记录保存到数据库中,使用购物车ID设置一个cookie,并返回一个true响应(如果失败,则返回false) 回到catalog.org,如果响应为true,则会向secure.com/cart/info发出另一个AJAX JSONP请求,该请求读取购

由于完全超出我控制范围的决定,我处于以下情况:

  • 我在catalog.org上有一个产品清单

  • 单击产品上的“添加到购物车”按钮会向secure.com/product/Add/[productKey]发出一个AJAX JSONP请求,该请求将购物车记录保存到数据库中,使用购物车ID设置一个cookie,并返回一个true响应(如果失败,则返回false)

  • 回到catalog.org,如果响应为true,则会向secure.com/cart/info发出另一个AJAX JSONP请求,该请求读取购物车ID cookie,获取记录,并返回购物车中的项目数

  • 再次回到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 developer tools中的缓存>“查看cookie信息”时,不会显示购物车ID cookie。它应该在那里,就像在其他浏览器和我们的开发和测试环境中一样

我相信现在发生的是IE阻止了第三方cookies。我们已经在secure.com上的所有请求中添加了P3P compact策略头,但cookie仍然没有设置。我们正在设置的标题是:

P3P: CP="CAO PSA OUR"
为什么在IE8-IE10中添加压缩策略头不能解决这个问题?我怎样才能在IE的所有版本中解决这个问题

解决方案

下面有几个好主意。我接受了@sdecima,因为它听起来最有希望。我们最终结合了其中一些想法,但成功地避免了XDomainRequest:

  • 单击产品上的“添加到购物车”按钮可生成AJAX JSONP 请求secure.com/product/add/[productKey],保存购物车 记录到数据库,设置带有购物车ID的cookie,并返回 响应为true(如果失败,则为false)
我们更改了secure.com/product/add上的操作,以返回一个JSON对象,该对象带有一个布尔值,指示成功或失败以及购物车ID

  • 回到catalog.org,如果响应为真,那么另一个AJAX JSONP 请求发送到secure.com/cart/info,它读取购物车ID cookie,获取记录,并返回 推车
我们更改了回调函数以检查响应对象中的两个属性。如果success为true且购物车ID存在,我们将在页面上创建一个隐藏的iframe。iframe的
src
属性设置为我们添加到secure.com的新端点。此操作接受购物车ID参数并保存购物车ID cookie。我们不再需要将cookie保存在secure.com/product/add操作中

接下来,我们更改了secure.com/cart/info上的操作以接受cart ID参数。此操作将使用购物车ID参数(如果存在)获取购物车信息,否则它仍将尝试读取cookie。如果我们可以保证iframe已经完成加载,并且cookie已经保存在secure.com上,那么这个额外的检查将是不必要的,但是由于浏览器安全限制,我们无法知道iframe何时已经在catalog.org上完成加载

最后,在IE7-IE10中仍然需要P3P头
CP=“CAO PSA OUR”
。(是的,这在IE7中也适用:)

我们现在有了一个解决方案(尽管非常复杂),用于保存和访问跨域Cookie,该解决方案在所有主流浏览器中都能运行,至少在我们能够可靠测试的时候是如此


我们可能会对其进行更多的重构。首先,到secure.com/cart/info的第二个AJAX JSONP请求在这一点上是多余的,因为我们可以将原始请求中需要的所有信息返回到secure.com/product/add action(将该操作更改为返回JSON对象的一个附带好处——此外,我们还可以返回一条错误消息,确切地指出在出现错误时失败的原因).

一句话:第三方cookie通常被隐私/广告阻止扩展阻止,应该被认为是不可靠的。如果将其留在生产中,你将自食其果

语法表明端点有一天会变得RESTful的野心。唯一的问题是使用cookies,这会将整个“无状态”概念抛到脑后!理想情况下,应该对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。冲洗并重复

瞧,你刚刚持久化了一个活动的用户购物车,没有用cookies污染API调用。去对你的架构师大喊大叫吧。如果可以的话
callback({"exampleKey": "exampleValue"});
document.cookie="cartID=1234";
callback({"exampleKey": "exampleValue"});