服务器响应 json 字符串的两种格式,有点蒙圈

2016-05-10 17:53:19 +08:00
 LinJunzhu

1 、别家的服务器返回数据,在 Chrome 中的 response 查看为:

{"message":"查询成功","data": "yo"}

2 、有人的服务器返回是:

"{\"rateInfos\":[]}"

第一种就直接是 json 对象了,第二种是字符串,为什么呢?按道理 http 传输过程中,数据应该都是字符串,为何第一种可以直接为 json 对象了呢?

查看了下,两者的 response header 都有: Content-Type: application/json

有点蒙圈,求解答

3052 次点击
所在节点    问与答
13 条回复
bdbai
2016-05-10 18:19:15 +08:00
第一种看起来正常一点,第二种是直接拿去 eval 了吧。
wesley
2016-05-10 18:25:45 +08:00
没啥好蒙的, 把第二个的开发人员拖出来弹 JJ 1000 遍
learnshare
2016-05-10 18:25:52 +08:00
第二种错了,那只是字符串。问题出在后端, content-type 和内容不一致。
just1
2016-05-10 18:30:20 +08:00
第二个代码写错了吧
JiShuTui
2016-05-10 18:33:21 +08:00
下面这种情况是可以的
{"message":"查询成功","data": "yo","data2":"{\"rateInfos\":[]}"}
miyuki
2016-05-10 19:36:12 +08:00
正常人写的的都是第一种
Pure88
2016-05-10 22:11:57 +08:00
@wesley 上下左右各弹 250 遍?
murmur
2016-05-10 22:35:13 +08:00
第二个如果没有 jsonp 的 callback 直接拉出去打
sensui7
2016-05-10 22:59:37 +08:00
网络丄传输的都是字符串, 这是肯定的, 区别就是一种字符串包含的是 json 编码,楼猪第一个就是这种字符串,
另一种是普通字符串, 你的第二个 , 只不过这是手动写成了 json 格式了. 相当于 手动版 json_encode
LinJunzhu
2016-05-10 23:21:27 +08:00
唔,我想了下:

第一种,是因为服务器返回了 json 对象,并且服务器语言有相应的序列化 json 接口,在传输时会将 json 对象序列化,浏览器或语言 接收到该响应时,根据 content_type 去反序列解析响应,所以会直接拿到 json 对象。

第二种,是因为浏览器返回的就是 json 字符串,所以客户端拿到的响应当然仅仅只是字符串了。

不知道对不对呢?
LinJunzhu
2016-05-10 23:24:46 +08:00
@sensui7 感谢,不过我有个疑问,客户端是如何知道这个这个字符串是 json 编码并且进行反序列化呢?。 因为第二种 json 字符串,也符合 json 规范,也是可以进行 parse 操作的呀?
congeec
2016-05-10 23:35:53 +08:00
打死也不能 eval() !!!!
用 JSON.parse()
LinJunzhu
2016-05-11 11:52:57 +08:00
通过不断 google + 实验,我觉得我得到了答案。

首先, response header 内的 content_type 仅仅只是表明响应数据是怎样的数据,并不会自动去解析成 JSON 对象 (注: 有浏览器原生 JSON 对象,其他的都为语言的对象)。

比如原生 AJAX ,拿到该响应,仅仅只是 string 。 而 jQuery 则会根据 content_type 去将响应解析成对应的格式

至于浏览器开发者工具,你看到的 JSON 对象,是浏览器开发者工具为了方便我们开发,自己将它解析成了对应的格式。

接着,当你在服务手动创建:
```ruby
# Rails
render text: '{"a": "a"}', content_type: "application/json"
```

此时你在浏览器就会看到问题内的第一种情况,也即正常情况。 浏览器会根据 content_type 将他解析

```ruby
# Rails
render json: { a: 'a' }
```
此时, Rails 会自动将他序列化成字符串(即跟手动创建字符串没两样),然后进行传输。

那么,问题第二种情况是怎样的呢?如果服务器仅仅只是返回 JSON 字符串的话,那么肯定也是会自动解析的呀。答案在于服务器的开发人员傻了。

```ruby
# 正常情况
'{"a": "a"}'

# 而开发人员由于某种原因,将 json 字符串又序列化了一遍
# 类似于这种效果
JSON.stringify(JSON.stringify(jsonObejct))

# 因此最终服务器返回的字符串其实是:
"\"{\\\"a\\\": \\\"a\\\"\}\""

# 浏览器拿到的字符串解析后是:
"{\"a\": \"a\"}"

```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/277692

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX