根据几年前对一个相同问题的回答,Javascript中的encodeURIComponent(str)应该等同于urllib。引用(str, safe='~()*!. ")通过扩展,我猜decodeuriccomponent (str)将等同于urllib.unquote(str)。
根据我的经验,情况并非如此。我正在编写一些网络代码,从Python服务器到网站上的客户端进行通信,我得到了不同的结果。
我正在生成一个唯一的ID,并使用几乎与以下代码相同的东西通过TCP发送它:
import urllib
import struct
import random
def sendID():
id = random.SystemRandom().getrandbits(128)
upper = id >> 64
lower = id & 0xFFFFFFFFFFFFFFFF
packed = struct.pack('<B2Q', 0x00, upper, lower)
encoded = urllib.quote(packed, safe='~()*!.'')
# the below line is just sending it over an already established TCP connection
# the code is irrelevant as I already this is working as expected
sendtoclient(encoded)
客户端在以下websocket对象回调中接收消息:
this.websocket.onmessage = function (msg) {
console.log(msg.data);
var sType = bufferpack.unpack('<B', decodeURIComponent(msg.data).substring(0, 1));
console.log(sType);
};
这应该解码msg。
将sType设置为打包数据的第一个"部分"(在本例中为0x00)。我遇到的问题是这些函数没有按我的预期工作。在JSFiddle和Python命令行中进行了一些测试后,我得到了编码/解码uricomponent和urllib的不同结果。报价/结束函数。encodeURIComponent只是给了我一个与"等效"urllib不同的结果。引用,并且decodeuriccomponent会导致一个错误的URI错误。
可以在下面的示例中看到:
>>> import random
>>> import urllib
>>> import struct
>>> id = random.SystemRandom().getrandbits(128)
>>> upper = id >> 64
>>> lower = id & 0xFFFFFFFFFFFFFFFF
>>> packed = struct.pack('<B2Q', 0x00, upper, lower)
>>> encoded = urllib.quote(packed, safe='~()*!.'')
>>> id
79837607446780471980532690349264559028L
>>> upper
4328005371992213727L
>>> lower
4092443888854326196L
>>> packed
'x00xdfx08x94x7fxf4)x10<xb4[axc2x08Hxcb8'
>>> encoded
'%00%DF%08%94%7F%F4)%10%3C%B4%5Ba%C2%08H%CB8'
然而,当我使用encodeURIComponent和decodeURIComponent对"包装"one_answers"编码"分别我得到一个不同的编码值和解码抛出一个错误。输出后的Javascript如下所示:
console.log(encodeURIComponent('x00xdfx08x94x7fxf4)x10<xb4[axc2x08Hxcb8'))
console.log(decodeURIComponent('%00%DF%08%94%7F%F4)%10%3C%B4%5Ba%C2%08H%CB8'));
% 00% C3 c2 % % 9 f % 08% 94% 7 f % C3%B4) % 10% 3 c % C2%B4 % 5英航% C3 % 82% 08年8 h % C3 % b8(index):50 Uncaught URIError: URI malformed
JSFiddle片段与上述Javascript代码为您的方便。
最后,我的实际问题是:上面使用的函数(引号/反引号和encode/decodeuriccomponent)实际上是等效的吗?如果没有,有人可以建议代码更改或其他库/函数,可以做我所期望的(编码/解码和打包/解包值在客户端和服务器端是相同的)?
在使用了我的示例代码并阅读了一些关于类似问题的其他资源之后,我发现'打包'字符串是使用'latin-1'字符集和那个urllib进行编码的。Quote不能正常工作
下面我从我的python解释器中包含了相同的示例,并添加了一些额外的行,以显示使用适当的编码函数urllib。在处理utf-8时,quote/unquote和encode/decodeuriccomponent实际上是等价的。
>>> import random
>>> import urllib
>>> import struct
>>> id = random.SystemRandom().getrandbits(128)
>>> upper = id >> 64
>>> lower = id & 0xFFFFFFFFFFFFFFFF
>>> packed = struct.pack('<B2Q', 0x00, upper, lower)
>>> encoded = urllib.quote(packed, safe='~()*!.'')
>>> id
79837607446780471980532690349264559028L
>>> upper
4328005371992213727L
>>> lower
4092443888854326196L
>>> packed
'x00xdfx08x94x7fxf4)x10<xb4[axc2x08Hxcb8'
>>> encoded
'%00%DF%08%94%7F%F4)%10%3C%B4%5Ba%C2%08H%CB8'
>>> packed.decode('latin-1')
u'x00xdfx08x94x7fxf4)x10<xb4[axc2x08Hxcb8'
>>> packed.decode('latin-1').encode('utf-8')
'x00xc3x9fx08xc2x94x7fxc3xb4)x10<xc2xb4[axc3x82x08Hxc3x8b8'
>>> urllib.quote(packed.decode('latin-1').encode('utf-8'), safe='~()*!.'')
'%00%C3%9F%08%C2%94%7F%C3%B4)%10%3C%C2%B4%5Ba%C3%82%08H%C3%8B8'
输出
' % 00% C3 c2 % % 9 f % 08% 94% 7 f % C3%B4) % 10% 3 c % C2%B4 % 5英航% C3 % 82% 08年8 h % C3 % b8"
匹配
输出的内容在Javascript。encodeURIComponent(" x00 xdf ( x94 x7f x10<xf4); [ xc2 x08H xb4 xcb8")