通过不断 google + 实验,我觉得我得到了答案。
首先, response header 内的 content_type 仅仅只是表明响应数据是怎样的数据,并不会自动去解析成 JSON 对象 (注: 有浏览器原生 JSON 对象,其他的都为语言的对象)。
比如原生 AJAX ,拿到该响应,仅仅只是 string 。 而 jQuery 则会根据 content_type 去将响应解析成对应的格式
至于浏览器开发者工具,你看到的 JSON 对象,是浏览器开发者工具为了方便我们开发,自己将它解析成了对应的格式。
接着,当你在服务手动创建:
# Rails
render text: '{"a": "a"}', content_type: "application/json"
此时你在浏览器就会看到问题内的第一种情况,也即正常情况。 浏览器会根据 content_type 将他解析
# Rails
render json: { a: 'a' }
此时, Rails 会自动将他序列化成字符串(即跟手动创建字符串没两样),然后进行传输。
那么,问题第二种情况是怎样的呢?如果服务器仅仅只是返回 JSON 字符串的话,那么肯定也是会自动解析的呀。答案在于服务器的开发人员傻了。
# 正常情况
'{"a": "a"}'
# 而开发人员由于某种原因,将 json 字符串又序列化了一遍
# 类似于这种效果
JSON.stringify(JSON.stringify(jsonObejct))
# 因此最终服务器返回的字符串其实是:
"\"{\\\"a\\\": \\\"a\\\"\}\""
# 浏览器拿到的字符串解析后是:
"{\"a\": \"a\"}"