由于我完全无法控制的决定,我处于以下情况:
我在 catalog.org 上有一个产品列表
单击产品上的“添加到购物车”按钮向 secure.com/product/add/[productKey] 发出 AJAX JSONP 请求,该请求将购物车记录保存到数据库,使用购物车 ID 设置 cookie,并返回 true响应(如果失败,则返回 false)
返回catalog.org,如果响应为真,则向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 是安全的。 development.com 和secure.test.com 分别。
但是,在我们部署到生产环境后,这在 IE8 - IE10 中停止工作。将产品添加到购物车后,购物车中的商品数量会在 catalog.org 上成功更新。然后,单击 catalog.org 上的“转到购物车”按钮后,secure.com 上的购物车摘要什么也没有显示,因为它无法读取 cookie。在 IE 开发者工具中转到缓存 >“查看 cookie 信息”显示没有购物车 ID cookie。它应该在那里,就像它在其他浏览器以及我们的开发和测试环境中一样。
我相信正在发生的事情是 IE 正在阻止第三方 cookie。我们已为secure.com 上的所有请求添加了一个P3P 紧凑策略标头,但仍未设置cookie。我们设置的标题是:
P3P: CP="CAO PSA OUR"
为什么在 IE8 - IE10 中添加紧凑策略标头不能解决此问题?如何解决此问题以在所有版本的 IE 中工作?
解决方案
下面有几个好主意。我接受了@sdecima,因为它听起来最有希望。我们最终结合了其中一些想法,但设法避免了 XDomainRequest:
- 单击产品上的“添加到购物车”按钮向 secure.com/product/add/[productKey] 发出 AJAX JSONP 请求,该请求将购物车记录保存到数据库,使用购物车 ID 设置 cookie,并返回 true响应(如果失败,则返回 false)
我们更改了 secure.com/product/add 上的操作以返回一个 JSON 对象,其中包含一个指示成功或失败的布尔值和购物车 ID。
- 返回catalog.org,如果响应为真,则向secure.com/cart/info 发出另一个AJAX JSONP 请求,读取购物车ID cookie,获取记录,并返回购物车中的商品数量
我们更改了回调函数以检查响应对象中的两个属性。如果成功并且购物车 ID 存在,我们会在页面上创建一个隐藏的 iframe。iframe的src
属性设置为我们添加到 secure.com 的新端点。此操作接受购物车 ID 参数并保存购物车 ID cookie。我们不再需要将 cookie 保存在 secure.com/product/add 操作中。
接下来,我们更改了 secure.com/cart/info 上的操作以接受购物车 ID 参数。此操作将使用购物车 ID 参数(如果存在)来获取购物车信息,否则仍会尝试读取 cookie。如果我们可以保证 iframe 已完成加载并且 cookie 已保存在 secure.com 上,则无需进行额外检查,但由于浏览器安全限制,我们无法知道 iframe 何时完成在 catalog.org 上的加载。
最后,CP="CAO PSA OUR"
仍然需要 P3P 标头才能在 IE7 - IE10 中工作。(是的,这现在也适用于 IE7 :)
我们现在有一个解决方案(尽管是一个非常复杂的解决方案),用于保存和访问在所有主要浏览器中都可以使用的跨域 cookie,至少在我们可以可靠测试的情况下。
我们可能会对此进行更多重构。一方面,此时对secure.com/cart/info 的第二个AJAX JSONP 请求是多余的,因为我们可以将原始请求中所需的所有信息返回到secure.com/product/add 操作(更改的附带好处该操作返回一个 JSON 对象——另外,如果出现错误,我们可以返回一条错误消息,指出它失败的确切原因)。