2016-07-04 10 views
1

これによると、数年前に同じ質問に与えられたanswerによれば、JavascriptのencodeURIComponent(str)はPythonのurllib.quote(str、safe = '〜()*!\' ')と同等でなければなりません。拡張によって、私はdecodeURIComponent(str)がurllib.unquote(str)と同等であると推測しました。urllib.quoteとurllib.unquoteに相当するJavascriptがありますか?

これは私の経験からのケースではありません。私は、PythonサーバーからWebサイト上のクライアントに通信するためのネットワークコードを書いています。私は別の結果を得ています。

私は、ユニークな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をパックデータの最初の部分(この場合は0x00)に設定する必要があります。

私が遭遇している問題は、これらの機能が期待どおりに動作していないことです。 JSFiddleとPythonのコマンドラインでいくつかのテストを行った後、encode/decodeURIComponentとurllib.quote/unquote関数の結果が異なります。 encodeURIComponentは私に 'equivalent' urllib.quoteと異なる結果を与え、decodeURIComponentは不正なURIエラーをもたらします。

これは、以下に示すサンプルで見ることができます。私は、それぞれ「充填」と「符号化」にencodeURIComponentでとは、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' 

は、しかし、私は、異なる符号化された値を取得し、復号はエラーをスロー。 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

私のサンプルコードでもう少し遊んで、同様の問題について他のリソースを読んだところ、私は 'packin'文字列が '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' 

出力JavaScriptで

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

で出力したものを

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

試合。

関連する問題