13

我正在构建一个购物车,当按下“购买”按钮时,Web 服务会返回一个 JSON 输出,然后我将其作为字符串保存到 Javascript cookie 中。

Web 服务的典型返回可能是:

{
   "d":{
      "58658":{
         "id":"58658",
         "qty":"1",
         "singlePrice":"754",
         "salePrice":"754",
         "isBulk":"0",
         "isSor":"0",
         "vatRate":"20.00",
         "masterCat":"6",
         "imgUrl":"http://...img url",
         "singleWeight":"18000",
         "totalAvailableStock":"2",
         "thirdPartyStock":"",
         "item":"Electrovoice Live X Elx115p, Each " // << HERE IS THE ISSUE
      }       
   }
}

当返回看起来像上面时,它只会在 Safari 中失败

花了很多时间试图找到一些有用的机制来调试它而无需购买 Mac,我终于找到了它:

"item":"Electrovoice Live X Elx115p, Each " // << HERE IS THE ISSUE - The comma

item值在字符串中有一个逗号,我将返回值保存到一个 cookie 中,如下所示:

cookies.set('shopping_cart', JSON.stringify(result)); // (where result is the JSON above)

当我稍后尝试回忆时:

var shopping_cart = cookies.get('shopping_cart');
shopping_cart = JSON.parse(shopping_cart);

它在每个浏览器中都可以正常工作,甚至显然是 Internet Explorer ......除了 Safari

我没有 Mac,所以不确定 Mac 上的 Safari 是否有任何不同,但 Windows 版本肯定有这个错误,在我的 iPhone 和 iPad 上也是如此。

错误是:

JSON parse error, unterminated string.

正如我所说,这似乎只是 Safari 中的一个问题,但很难找到解决方案。

非常感谢帮助!

编辑:

我创建了一个小提琴:http: //jsfiddle.net/jhartnoll/2GLEz/ 这个小提琴将复制问题,它与将数据作为字符串存储在 Cookie 中并将其重新解析为 JSON 有关

但是,由于我已将我的 Cookie 函数作为外部资源 ( http://www.sam.thinkka.com/clientscripts/cookie_test.js ) 包含在内,因此您需要确保 Safari 不会阻止第三方 cookie。

4

2 回答 2

14

好的,现在我们已经找到了实际问题的根源,我想我可以提供帮助。

问题基本上是您将数据存储到 cookie 字符串中但没有转义它。因此,当您设置 cookie 并且它包含逗号时,可以将逗号视为 cookie 分隔符。对于您的大部分字符串,JSON 中的引号似乎掩盖了这种效果(引号也是 cookie 的相关字符),但对于这个,cookie 解析器将其视为分隔符。

这反过来意味着它被视为 cookie 的结尾,这意味着当您将其加载回来时,它会在该点被截断。

解决方案:在将其保存为 cookie 之前转义字符串。(你的makeCookie()函数应该这样做)。您应该能够为此使用 JSescape()函数。

请参阅cookie 规范,并注意逗号、双引号、分号等是 cookie 的相关字符。

另见:这个类似的问题

至于为什么它发生在 Safari 而不是其他浏览器中......我想这可能与其他任何事情一样多取决于运气。也许其他浏览器的 cookie 解析器识别出逗号后的以下字符串无效,因此可以确定逗号不用作分隔符。

您可能还想查看MDN cookie 文章,其中包含示例 JS coookie 库的代码,该库确实进行了所有正确的转义。您可能需要考虑使用此库而不是您自己当前的代码。(或至少部分)

希望有帮助。

最后,稍微偏离主题,但在使用 cookie 时需要注意的另一件事:不要忘记,对于您网站上的每个 http 请求,整个 cookie 字符串都是双向传输的。因此,如果您有 4k 的 cookie 数据,这意味着您网站上的每个 html、css、js 和图像文件需要额外的 8k 带宽。

如果您使用的是大型 cookie,则可以使用其他方法来存储不受此问题影响的本地数据。这篇文章可能对你有所帮助。

于 2013-10-14T14:08:13.047 回答
0

你不需要解析这个json......试试:

var a= {
    "d":{
        "58658":{
            "id":"58658",
            "qty":"1",
            "singlePrice":"754",
            "salePrice":"754",
            "isBulk":"0",
            "isSor":"0",
            "vatRate":"20.00",
            "masterCat":"6",
            "imgUrl":"http://...img url",
            "singleWeight":"18000",
            "totalAvailableStock":"2",
            "thirdPartyStock":"",
            "item":"Electrovoice Live X Elx115p, Each " // << HERE IS THE ISSUE
        }
    }
}

console.log(a.d['58658'])
于 2013-10-14T11:50:59.763 回答