当字符串值包含逗号时,JSON.parse在Safari中失败 [英] JSON.parse Fails in Safari when a string value contains a comma

查看:153
本文介绍了当字符串值包含逗号时,JSON.parse在Safari中失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



来自网络服务的典型回报可能是:

  {
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,每个//<<这里是问题
}
}
}

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



花了很多时间试图找到一些有用的机制来调试这个而不用买Mac,我终于追踪到:

 item:Electrovoice Live X Elx115p,每个//<<这里是问题 - 逗号

项目 value在字符串中有逗号,我将返回值保存到cookie中,其中包含:

  cookies.set(' shopping_cart',JSON.stringify(result)); //(结果是上面的JSON)

当我稍后再试一次时:

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

它在每个浏览器中都能正常工作,显然,Internet Explorer ......除了Safari



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



错误是:

  JSON解析错误,未终止的字符串。 

正如我所说,这似乎仅在Safari中存在问题,但我很难找到解决方案。



非常感谢!



编辑:



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



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

解决方案

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



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



这反过来意味着它被视为cookie的结尾,这意味着当你加载它时它会被截断。



<解决方案:在将其保存为cookie之前,先转义字符串。 (你的 makeCookie()函数应该这样做)。您应该可以使用JS escape()函数。



参见 Cookie规范,请注意逗号,双引号,分号等是Cookie的相关字符。



参见:这个类似的问题



至于它为什么会在Safari而不是其他浏览器中发生...我想这可能与其他任何东西一样都有运气。也许其他浏览器的cookie解析器识别出逗号后面的以下字符串无效,从而确定逗号不是分隔符。



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



希望有所帮助。



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



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


I am building a shopping cart which when a "Buy" button is pressed, a web service returns a JSON output which I then save into a Javascript cookie as a string.

A typical return from the web service might be:

{
   "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
      }       
   }
}

When the return looks like the above, it will fail in Safari ONLY

Having spent a lot of time trying to find some useful mechanism to debug this without buying a Mac, I have finally tracked it down to:

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

The item value has a comma in the string, I save my return value into a cookie with something like:

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

When I try to recall it later:

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

It works fine in EVERY browser, even, apparently, Internet Explorer... EXCEPT Safari

I don't have a Mac so not sure if Safari on Mac is any different, but certainly the Windows version has this error, and so it does on my iPhone and iPad.

The error is:

JSON parse error, unterminated string.

As I say, this appear to be an issue only in Safari, am having difficulty finding a solution though.

Help much appreciated!

EDIT:

I have created a Fiddle: http://jsfiddle.net/jhartnoll/2GLEz/ This Fiddle will replicate the issue, it is relating to storing the data as a string in a Cookie and the re-parsing it to JSON

But, because I have included my Cookie functions as an External Resource (http://www.sam.thinkka.com/clientscripts/cookie_test.js) you will need to ensure that Safari is not blocking third party cookies.

解决方案

Okay, now we've got to the root of the actual problem, I think I can help.

The problem is basically that you're storing data into the cookie string but not escaping it. So when you set the cookie and it contains commas, the commas can be seen as cookie delimiters. For most of your string, the quotes in the JSON seem to be masking this effect (quotes are also relevant characters for cookies), but for this one it is being seen by the cookie parser as a delimiter.

This in turn means that it is seen as the end of the cookie, which means when you load it back it is truncated at that point.

Solution: Escape the string before saving it as a cookie. (your makeCookie() function should do this). You should be able to use the JS escape() function for this.

See the cookie spec, and note that commas, double quotes, semi-colons, and more are relevant characters for cookies.

See also: this similar issue

As for why it's happening in Safari and not other browsers... I guess that's probably down to luck as much as anything else. Maybe the other browsers' cookie parsers recognise that the following string after the comma isn't valid and thus work out that the comma isn't intended as a delimiter.

You might also want to see the MDN cookie article which includes code for a sample JS coookie library, which does do all the proper escaping. You may want to consider using this lib instead of your own current code. (or at least parts of it)

Hope that helps.

Finally, slightly off topic, but one additional thing to be aware of when using cookies: Don't forget that the entire cookie string is transmitted in both directions for every single http request made on your site. So if you've got 4k of cookie data, that means an additional 8k of bandwidth for every html, css, js and image file on your site.

If you're using large cookies, there are alternative ways to store local data which are not subject to this problem. This article might be helpful for you.

这篇关于当字符串值包含逗号时,JSON.parse在Safari中失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆