В соответствии с этим 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), фактически эквивалентны? Если кто-то не может предложить изменения кода или другие библиотеки/функции, которые могли бы делать то, что я ожидаю (кодированное/декодированное и упакованное/неупакованное значение одинаково на стороне клиента и сервера)?