Having encoded a unicode string in javascript, how can I decode it in Python?
App Engine平台:webapp WSGI的CGI框架:/ /
在我的客户端(JS)、I(URL url结构带有一concatenating Unicode字符串:
1 | http://www.foo.com/地震 |
然后我打电话给encodeuri to get
1 | http://www.foo.com/%E5%9C%B0%E9%9C%87 |
我把这个HTML表单中的值。
PayPal的形式提交给大家,在我已经设置到UTF-8编码。
然后通过PayPal的IPN)使请求的URL后说。
在我的服务器端,wsgiapplication tries提取使用的Unicode字符串的正则表达式,我定义为:
1 | (r'/paypal-listener/(.+?)', c.PayPalIPNListener) |
我尝试把它通过调用解码
1 | query = unquote_plus(query).decode('utf-8') |
(或变异),但我得到的错误
/paypal-listener/%E5%9C%B0%E9%9C%87
... (ommited) ...
'ascii' codec can't encode characters
in position 0-1: ordinal not in
range(128)
(在第一行是请求的URL)
当我检查的长度
原则上,这应该起作用:
1 2 | >>> urllib.unquote_plus('http://www.foo.com/%E5%9C%B0%E9%9C%87').decode('utf-8') u'http://www.foo.com/\u5730\u9707' |
但是,请注意:
一般来说,你不应该引用整个URL。URL组件中具有特殊含义的字符将丢失。您应该将URL拆分为多个部分,获取您感兴趣的单一路径名组件(
(如果你想把一个URI完全转换成一个IRI,比如
This gets received in my python server side.
服务器端到底是什么?服务器、网关、框架?你是如何得到
您似乎得到了一个
不幸的是,一些Web服务器存在一些严重的问题,这些问题使得在URL的路径名部分使用Unicode非常不可靠,不仅仅是在Python中,而且通常情况下。
主要问题是,
IIS是一个特殊的问题,因为它将尝试默认将URL路径解析为utf-8,如果路径不是有效的utf-8序列,但没有告诉您,它将返回到非常不可靠的系统默认代码页(例如,在西Windows安装中的cp1252)。然后,在从环境变量映射中读取
Apache通过提供一个额外的非标准环境
一些框架试图通过不同程度的成功来解决这些问题。WSGI 1.1有望在标准化这一点上有所突破,但与此同时,我们所处的实际位置是Unicode路径不会在任何地方都起作用,试图在一台服务器上修复它的黑客通常会在另一台服务器上破坏它。
可以始终使用URL重写将Unicode路径转换为Unicode查询参数。由于
假设HTML页面是以UTF-8编码的,那么如果框架解码了URL百分比,那么它应该只是一个简单的
如果没有,可以使用:
- 如果URL是
http://www.foo.com/地震 ,则返回urllib.unquote(path).decode('utf-8') 。 - 如果您谈论的是通过Ajax或HTML
发送的参数,则为
urllib.unquote_plus(path).decode('utf-8') 。
(见http://docs.python.org/library/urlib.html_urlib.unquote)
编辑:如果您仍有问题,请向我们提供以下信息以帮助我们跟踪此问题:
- 您在Google应用程序引擎内部使用的Web框架,例如django、webob、cgi等
- 如何在应用程序中获取URL(如果可以,请添加一个简短的代码示例)
- 添加
http://www.foo.com/地震 作为url 尝试将其添加为URL并发布
repr(url) ,这样我们就可以确保服务器不会将字符解码为拉丁语-1或Windows-1252:1http://foo.com/?¢£¤¥|§¨?a??-?ˉ°±23′μ?·?1o?????àá??????èéê?ìí??D?òó???×?ùú?üYT?àáa?????èéê?ìí??e?òó???÷?ùú?üyt?
编辑2:查看它是一个实际的URL(而不是在查询部分,即不是
1 | query = unquote(query.encode('ascii')).decode('utf-8') |
可能是安全的。如果您正在解码实际的URL,应该是
在这种情况下,
这工作:
1 2 3 4 5 | >>> u = u'http://www.foo.com/%E5%9C%B0%E9%9C%87' >>> print urllib.unquote(u.encode('ascii')) http://www.foo.com/地震 >>> print urllib.unquote(u.encode('ascii')).decode('utf-8') http://www.foo.com/地震 |
这不是(另请参见urllib.unquote解码拉丁语1的百分比转义):
1 2 | >>> print urllib.unquote(u) http://www.foo.com/? °é |
解码已使用Unicode的字符串不起作用:
1 2 3 4 5 6 7 8 | >>> print urllib.unquote(u).decode('utf-8') Traceback (most recent call last): File"<input>", line 1, in <module> File".../lib/python2.6/encodings/utf_8.py", line 16, in decode return codecs.utf_8_decode(input, errors, True) UnicodeEncodeError: 'ascii' codec can't encode characters in position 19-24: o rdinal not in range(128) |
通常有一个服务器端语言的函数来解码URL,也可能有一个在Python中。您也可以在您的案例中使用javascript的
啊啊,可怕的
'ascii' codec can't encode characters in position... ordinal not in range
错误。在用Python处理日语等语言时不可避免…
在这种情况下,这不是URL编码/解码问题。您的数据很可能已经解码并准备就绪。
我试着摆脱"解码"的电话,看看会发生什么。如果你得到垃圾,但没有错误,这可能意味着人们发送给你的数据,在另一个可爱的日本具体编码:eucjp,iso-2022-jp,shift-jis,甚至可能是难以捉摸的iso-2022-jp-ext,这是目前只有很少在野外发现。不过,后一种情况似乎不大可能发生。
edit:id还可以参考:编码/解码有什么区别?