[英]JSON.parse returns string instead of object
我正在编写一个 websocket 客户端,我想以 json 字符串的形式接收消息。 为此,我需要登录。 如果登录不正确,我会发送一个没有成功的 json 字符串。 JSON 字符串:
{"action":"login","args":["nosuccess"]}
在客户端上,我使用它来获取字符串:
WebSocket socket = new WebSocket("ws://localhost:2555/api");
socket.onmessage = function(evt) {
console.log(evt.data);
console.log(typeof(evt.data));
onMessage(evt);
}
function onMessage(evt) {
var data = JSON.parse(evt.data);
var action = data.action;
var args = data.args;
console.log(data);
console.log(typeof(data));
console.log(action);
console.log(args);
但是数据的类型是字符串......但为什么呢?
evt.data 返回:
"{\"action\":\"login\",\"args\":[\"nosuccess\"]}"
数据返回:
{"action":"login","args":["nosuccess"]}
WebSocket 服务器是一个 jetty 服务器,它发送一个字符串和一个字符串数组,在 json 中解析为 json 和 gson.toJson(class) Gson by Google。 Class 是一个包含字符串操作和字符串数组参数的类。
websocket.js的完整源码:
var socket;
function openWebsocket(adress) {
socket = new WebSocket(adress);
socket.onopen = function(evt) {
console.log("Socket opened [" + adress + "]");
};
socket.onclose = function(evt) {
loadPage("login.html");
console.log("Socket closed [" + evt.code + "]");
}
socket.onmessage = function(evt) {
onMessage(evt);
}
socket.onerror = function(evt) {
console.log("Socket couldn't connect [" + evt.message + "]");
showMessage("fa-exclamation-circle", "Socket couldn't be established!", 1000);
}
}
function onMessage(evt) {
var data = JSON.parse(evt.data);
var action = data.action;
var args = data.args;
console.log(data);
console.log(typeof(data));
console.log(action);
console.log(args);
$(".card-container h3").html(data);
if(action == "login") {
if(args[0] == "success") {
loadPage("dashboard.htm");
currentpage = "dashboard.htm";
showMessage("fa-check", "Du wurdest erfolgreich eingeloggt", 2000);
} else if(args[0] == "nosuccess") {
loadPage("login.html");
currentpage = "login.html";
showMessage("fa-exclamation-circle", "Falscher Benutzername oder falsches Passwort", 2000);
} else if(args[0] == "unauthenticated") {
loadPage("login.html");
currentpage = "login.html";
showMessage("fa-exclamation-circle", "Login failure: not authenticated", 2000);
}
}
}
function sendMessage(json) {
$(".card-container h3").html(JSON.stringify(json));
console.log(JSON.stringify(json));
socket.send(JSON.stringify(json));
}
如果我改变这一行:
var data = JSON.parse(evt.data);
对此:
var data = JSON.parse("{\"action\":\"login\",\"args\":[\"nosuccess\"]}");
然后它是一个 json 对象,但是当我使用 evt.data 时它是一个字符串。 如果我将行更改为:
var data = JSON.parse(JSON.parse(evt.data));
然后它就可以工作了,但是为什么,通常它应该只用一个 JSON.parse 来完成,是吗?
这似乎与过度字符串化的字符串相当一致。 例如,我使用FileReader.readAsText
加载了一个文本文件,它带有在控制台中呈现的\\n
和\\r
,所以我做了 - (JSON.stringify(reader.result)).replace(/(?:\\\\[rn])+/g, '')
首先查看符号,然后去掉它们。 接受它并在其上运行JSON.parse()
会将其转换为非转义字符串,因此再次运行JSON.parse()
会创建一个对象。
如果您不字符串化您的字符串,它将转换为一个对象,通常没有必要,但如果您无法控制获得的值,那么运行JSON.parse()
两次就可以了。
正如其他人在评论中所说的那样,这个问题似乎已经解决了。 如果您从服务器接收响应作为“字符串化对象”,那么您可以使用JSON.parse()将其转换为普通对象,如下所示:
var stringResponse = '{"action":"login","args":["nosuccess"]}';
var objResponse = JSON.parse(stringResponse);
console.log(objResponse.args);
您也可以在此处尝试上述代码。
至于为什么当您真正想要一个对象时服务器会返回一个字符串,这实际上归结为您的后端代码、您使用的库以及传输协议。 如果您只想让前端代码正常工作,请使用JSON.parse 。 如果您想编辑后端的响应方式,请提供更多信息。
检查的响应是正确的,因为它似乎是字符串过度字符串化的问题。 我在我的项目中使用 AWS Amplify AWSJSON 类型时遇到了它。 对我有用的解决方案是迭代多个(两次)以获取一个对象。
编写了一个简单的 JS 函数,用于解析时将返回一个对象。 没有真正的错误检查,而是一个起点。
export function jsonParser(blob) {
let parsed = JSON.parse(blob);
if (typeof parsed === 'string') parsed = jsonParser(parsed);
return parsed;
}
@DerpSuperleggera 是正确的。 问题确实是一个过度字符串化的字符串
let arr = "[\"~#iM\",[\"is_logged_out_token\",false,\"token_type\",\"Bearer\"]]"
所以要将它解析为一个对象,我只是通过JSON.parse
运行它两次,就成功了!
let obj = JSON.parse(JSON.parse(arr))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.