var sock = new SockJS(url, {'protocols_whitelist': ['xhr-polling']});
sock.onopen = function() {
var msg = {msg: "hello"};
sock.send(msg); // 1. example
sock.send(JSON.stringify(msg)); // 2.example
};
1。例如google chrome payload
["[object Object]"]
2。例如google chrome payload
["{\"msg\":\"hello\"}"]
我发现显式转换为字符串发生在sock.js这里(第253行):
https://github.com/sockjs/sockjs-client/blob/master/lib/sockjs.js#L253
这就是我直接发送js对象时看到["[object Object]"]
的原因(因为'' + data
将data
转换为字符串)。
that._transport.doSend(utils.quote('' + data));
SockJS.prototype.send = function(data) {
var that = this;
if (that.readyState === SockJS.CONNECTING)
throw new Error('INVALID_STATE_ERR');
if (that.readyState === SockJS.OPEN) {
that._transport.doSend(utils.quote('' + data)); // here
}
return true;
};
但是那个utils.quote确实
https://github.com/sockjs/sockjs-client/blob/master/lib/utils.js#L292
// Quote string, also taking care of unicode characters that browsers
// often break. Especially, take care of unicode surrogates:
// http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters#Surrogates
utils.quote = function(string) {
var quoted = quoteJSON(string);
// In most cases this should be very fast and good enough.
extra_escapable.lastIndex = 0;
if(!extra_escapable.test(quoted)) {
return quoted;
}
if(!extra_lookup) extra_lookup = unroll_lookup(extra_escapable);
return quoted.replace(extra_escapable, function(a) {
return extra_lookup[a];
});
};
最后:
https://github.com/sockjs/sockjs-client/blob/master/lib/utils.js#L261
var quoteJSON = (JSON3 && JSON3.stringify) || function(string) {
json_escapable.lastIndex = 0;
if (json_escapable.test(string)) {
string = string.replace(json_escapable, function(a) {
return json_lookup[a];
});
}
return '"' + string + '"';
};
正如您所看到的那样,当您想要发送JSON时,您需要通过自己显式调用JSON.stringify,并且Sock.js在您传递给sockjs_instance.send的字符串上再次发生同样的事情。
为什么需要编码两次?问题是我需要在服务器上做一些黑客来解码消息,因为单个JSON.decode不能正常工作,因为sock.js默认将all作为字符串数组发送。这是性能问题。
答案 0 :(得分:1)
正如您所看到的那样,当您想要发送JSON时,您需要通过自己显式调用JSON.stringify,并且Sock.js在您传递给sockjs_instance.send的字符串上再次发生同样的事情。
Websockets API假设数据传递给"发送"是文字。 (或二进制,SockJS不支持)。这就是"发送"呼叫期望它是文本。
SockJS确实需要对它进行编码,我们恰好使用json。 JSON很快(因为它经常内置)。实际上,我们使用代码中找到的修改后的JSON编码来避免unicode问题。
是的,理论上对于某些传输,在传递富数据时可以避免双重编码,但这样做不值得破坏与原生WS的兼容性。