有没有相当于urllib.quote和urllib.unquote的Javascript?

时间:2016-07-04 13:46:35

标签: javascript python-2.7 urllib

根据几年前给出的相同问题answer,Javascript中的encodeURIComponent(str)应该等同于urllib.quote(str,safe ='〜()*!。& #39;')在Python中。通过扩展,我猜想decodeURIComponent(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.data字符串并将sType设置为第一个&#39;部分&#39;打包数据(在本例中为0x00)。

我遇到的问题是这些功能无法正常工作。在JSFiddle和Python命令行中进行一些测试之后,我得到了编码/ decodeURIComponent和urllib.quote / unquote函数的不同结果。 encodeURIComponent只是给了我一个不同于&#39;等效的&#39; urllib.quote和decodeURIComponent导致格式错误的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
'\x00\xdf\x08\x94\x7f\xf4)\x10<\xb4[a\xc2\x08H\xcb8'
>>> encoded
'%00%DF%08%94%7F%F4)%10%3C%B4%5Ba%C2%08H%CB8'

然而,当我在&#39; packed&#39;上使用encodeURIComponent和decodeURIComponent时和&#39;编码&#39;我得到一个不同的编码值,解码引发错误。输出的Javascript如下所示。

console.log(encodeURIComponent('\x00\xdf\x08\x94\x7f\xf4)\x10<\xb4[a\xc2\x08H\xcb8'))
console.log(decodeURIComponent('%00%DF%08%94%7F%F4)%10%3C%B4%5Ba%C2%08H%CB8'));
  

00%%C3%9F%08%C2%94%7F%C3%B4)%10%3C%C2%B4%5Ba上%C3%82%08H%C3%8B8   (索引):50未捕获的URIError:URI格式错误

JSFiddle snippet with the above Javascript code for your convenience

最后,我的实际问题是:上面使用的函数(quote / unquote和encode / decodeURIComponent)实际上是等价的吗?如果没有,有人可以建议代码更改或其他库/函数可以做我期望的(客户端和服务器端的编码/解码和打包/解包值相同)?

1 个答案:

答案 0 :(得分:2)

在使用我的示例代码玩了一些其他资源并阅读有关类似问题的其他资源之后,我发现“包装好了”#39;字符串是使用&#39; latin-1&#39;字符集和urllib.quote无法正常工作。

下面我已经在我的python解释器中包含了相同的示例,其中有一些额外的行显示,在处理utf-8时,函数urllib.quote / unquote和encode / decodeURIComponent实际上是等效的。

>>> 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
'\x00\xdf\x08\x94\x7f\xf4)\x10<\xb4[a\xc2\x08H\xcb8'
>>> encoded
'%00%DF%08%94%7F%F4)%10%3C%B4%5Ba%C2%08H%CB8'

>>> packed.decode('latin-1')
u'\x00\xdf\x08\x94\x7f\xf4)\x10<\xb4[a\xc2\x08H\xcb8'
>>> packed.decode('latin-1').encode('utf-8')
'\x00\xc3\x9f\x08\xc2\x94\x7f\xc3\xb4)\x10<\xc2\xb4[a\xc3\x82\x08H\xc3\x8b8'
>>> 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'

输出

  

&#39;%00%C3%9F%08%C2%94%7F%C3%B4)%10%3C%C2%B4%5Ba上%C3%82%08H%C3%8B8&#39;

匹配

输出的内容
  

encodeURIComponent方法(&#39; \ X00 \ XDF \ X08 \ X94 \ 0x7F部分\ XF4)\ X10&LT; \ XB4并[a \ XC2 \ x08H \ xcb8&#39)

在Javascript中。

相关问题