2016-07-04 1 views
1

몇 년 전에 동일한 질문에 주어진이 answer에 따르면, 자바 스크립트의 encodeURIComponent (str)는 파이썬에서 urllib.quote (str, safe = '~() *!. \' ')와 동일해야합니다. 확장에 의해, 나는 decodeURIComponent (str)가 urllib.unquote (str)과 같을 것이라고 추측했을 것이다.urllib.quote 및 urllib.unquote에 해당하는 자바 스크립트가 있습니까?

내 경험으로는 그렇지 않습니다. 파이썬 서버에서 웹 사이트의 클라이언트로 통신하기위한 네트워킹 코드를 작성 중이며 다른 결과가 나타납니다.

나는 고유 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) 

메시지는 다음 웹 소켓 객체 콜백에서 클라이언트 측에 수신 :

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는 'equivalent'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가 '포장'및 I는 다른 인코딩 된 값을 가져 각각 '코드'를 사용하고 디코딩 에러가 발생 될 때. Javascript 다음에 출력이 나와 있습니다.

%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

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')); 
.

결국 실제 질문 : 위의 함수 (quote/unquote 및 encode/decodeURIComponent)가 실제로 사용되는 함수입니까? 그렇지 않으면 누군가가 코드 변경이나 다른 라이브러리/기능 (내가 인코딩/디코딩 및 압축/압축 해제 된 값이 클라이언트와 서버 측면에서 동일 함)을 수행 할 수 있다고 제안 할 수 있습니까?

답변

2

내 예제 코드로 좀 더 놀고 유사한 문제에 대한 다른 리소스를 읽은 후 '포장 된'문자열이 'latin-1'문자 집합을 사용하여 인코딩되었고 urllib.quote가 제대로 작동하지 않음을 발견했습니다. 그.

아래에는 파이썬 인터프리터의 동일한 예제가 포함되어 있는데, 몇 가지 추가 라인을 통해 적절한 인코딩을 통해 utll-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' 

출력

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

가 무엇 일치합니다.