webSocketクライアントを書いているIMと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サーバーは、Googleがgson.toJson(class)Gsonでjsonで解析したjsonの文字列と文字列配列を送信する桟橋サーバーです。 Classは、StringアクションとString配列引数を含むクラスです。
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));
それは動作しますが、なぜ、通常は1つのJSON.parseだけでそれを行う必要がありますか?
これは、over-stringified文字列とかなり一貫しているようです。たとえば、コンソールでレンダリングされた_FileReader.readAsText
_および_\n
_に付属する_\r
_を使用してテキストファイルをロードしたため、最初にシンボルを表示するために_(JSON.stringify(reader.result)).replace(/(?:\\[rn])+/g, '')
_を、次にそれらを取り除きます。それを取り、JSON.parse()
を実行すると、エスケープされない文字列に変換されるため、JSON.parse()
を再度実行するとオブジェクトが作成されます。
文字列を文字列化しない場合、オブジェクトに変換され、多くの場合必要ありませんが、取得した値を制御できない場合は、JSON.parse()
を2回実行するとうまくいきます。
他の人がコメントで述べているように、この問題は解決されたようです。サーバーから「文字列化オブジェクト」として応答を受信している場合、JSON.parse()で通常のオブジェクトに変換できます。 :
var stringResponse = '{"action":"login","args":["nosuccess"]}';
var objResponse = JSON.parse(stringResponse);
console.log(objResponse.args);
上記のコードを試すこともできます here 。
オブジェクトが本当に必要なときにサーバーが文字列を返す理由については、バックエンドコード、使用しているライブラリ、およびトランスポートプロトコルによって決まります。フロントエンドコードを機能させるだけの場合は、JSON.parseを使用します。バックエンドの応答方法を編集する場合は、詳細を入力してください。