2016-07-04 3 views
1

В соответствии с этим answer, заданному идентичному вопросу несколько лет назад, encodeURIComponent (str) в Javascript должен быть эквивалентен urllib.quote (str, safe = '~() *!. \' ') В Python. Расширением я бы предположил, что decodeURIComponent (str) будет эквивалентен urllib.unquote (str).Есть ли Javascript эквивалент urllib.quote и urllib.unquote?

Это не тот случай из моего опыта. Я пишу некоторый сетевой код для связи с сервера Python с клиентом на веб-сайте, и у меня разные результаты.

Я генерирует уникальный идентификатор и посылает его через 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 в первую «часть» упакованных данных (в данном случае 0x00).

Проблема, с которой я сталкиваюсь, заключается в том, что эти функции не работают, как я ожидал. После некоторого тестирования в JSFiddle и в командной строке Python, я получаю разные результаты для функций encode/decodeURIComponent и urllib.quote/unquote. encodeURIComponent просто дает мне другой результат из «эквивалентного» 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' 

Однако, когда я использую encodeURIComponent и decodeURIComponent на «упаковано» и «закодированы» соответственно я получаю другое кодированное значение и декодирование выдает ошибку. Ниже показан 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 (index):50 Uncaught URIError: URI malformed

JSFiddle snippet with the above Javascript code for your convenience.

Итак, мой фактический вопрос: являются ли функции, используемые выше (quote/unquote и encode/decodeURIComponent), фактически эквивалентны? Если кто-то не может предложить изменения кода или другие библиотеки/функции, которые могли бы делать то, что я ожидаю (кодированное/декодированное и упакованное/неупакованное значение одинаково на стороне клиента и сервера)?

ответ

2

После того, как я просмотрел еще несколько примеров кода и прочитал некоторые другие материалы о подобных проблемах, я обнаружил, что «упакованная» строка была закодирована с использованием набора символов «latin-1» и что urllib.quote не работал должным образом с что.

Ниже я включил тот же пример из моего интерпретатора python с несколькими дополнительными строками, показывающими, что при правильной кодировке функции urllib.quote/unquote и encode/decodeURIComponent на самом деле эквивалентны при работе с utf-8.

>>> 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' 

Выход

'%00%C3%9F%08%C2%94%7F%C3%B4)%10%3C%C2%B4%5Ba%C3%82%08H%C3%8B8'

соответствует тому, что было на выход

encodeURIComponent('\x00\xdf\x08\x94\x7f\xf4)\x10<\xb4[a\xc2\x08H\xcb8')

в JavaScript.

Смежные вопросы