我正在尝试编码和存储,并在Python中解码参数并在此过程中丢失。以下是我的步骤:
1)我使用google toolkit的gtm_stringByEscapingForURLArgument
正确转换NSString以传入HTTP参数。
2)在我的服务器(python)上,我将这些字符串参数存储为类似u'1234567890-/:;()$&@".,?!\'[]{}#%^*+=_\\|~<>\u20ac\xa3\xa5\u2022.,?!\''
的内容(请注意,这些是“123”视图中iphone键盘上的标准键和“#+ =”查看,\u
和\x
字符中有一些货币前缀,如英镑,日元等)
3)我在该存储的值上调用urllib.quote(myString,'')
,大概是为了将它们转移到客户端,以便客户端可以解除它们的转义。
结果是当我尝试记录%escaping的结果时出现异常。是否有一些关键步骤我忽略了需要使用\ u和\ x格式应用于存储的值才能正确转换它以通过http发送?
更新:标记为以下答案的建议对我有用。不过,我正在提供一些更新,以解决以下评论的问题。
我收到的例外情况引用了\u20ac
的问题。我不知道具体是否是一个问题,而不是它是字符串中第一个unicode字符的事实。
\u20ac
char是'euro'符号的unicode。除非我使用urllib2 quote
方法,否则我基本上发现我遇到了问题。
答案 0 :(得分:70)
url编码“原始”unicode并没有多大意义。您首先需要做的是.encode("utf8")
,因此您有一个已知的字节编码,然后是.quote()
。
输出不是很漂亮,但应该是正确的uri编码。
>>> s = u'1234567890-/:;()$&@".,?!\'[]{}#%^*+=_\|~<>\u20ac\xa3\xa5\u2022.,?!\''
>>> urllib2.quote(s.encode("utf8"))
'1234567890-/%3A%3B%28%29%24%26%40%22.%2C%3F%21%27%5B%5D%7B%7D%23%25%5E%2A%2B%3D_%5C%7C%7E%3C%3E%E2%82%AC%C2%A3%C2%A5%E2%80%A2.%2C%3F%21%27'
请记住,如果您正在调试或其他任何事情,则需要unquote()
和decode()
来正确打印出来。
>>> print urllib2.unquote(urllib2.quote(s.encode("utf8")))
1234567890-/:;()$&@".,?!'[]{}#%^*+=_\|~<>€£¥•.,?!'
>>> # oops, nasty  means we've got a utf8 byte stream being treated as an ascii stream
>>> print urllib2.unquote(urllib2.quote(s.encode("utf8"))).decode("utf8")
1234567890-/:;()$&@".,?!'[]{}#%^*+=_\|~<>€£¥•.,?!'
事实上,这是另一个答案中提到的django functions所做的。
功能 django.utils.http.urlquote()和 django.utils.http.urlquote_plus()是 Python标准的版本 urllib.quote()和urllib.quote_plus() 使用非ASCII字符。 (数据先前转换为UTF-8 编码。)
如果您使用任何进一步的引用或编码不要破坏东西,请小心。
答案 1 :(得分:4)
我想要第二次pycruft的评论。网络协议已经发展了数十年,处理各种惯例可能很麻烦。现在URL恰好没有为字符定义,只是为字节(八位字节)定义。作为一个历史巧合,URL是您只能假设但不强制执行或安全地期望编码存在的地方之一。然而,有一个惯例是喜欢latin-1和utf-8而不是其他编码。有一段时间,看起来“unicode percent escapes”将是未来,但它们从未流行过。
在这个领域迂回挑剔关于unicode
个对象和八位位组str
之间的区别是非常重要的(在Python&lt; 3.0;那个,令人困惑的是,str
unicode Python中的对象和bytes
/ bytearray
个对象&gt; = 3.0)。不幸的是,根据我的经验,出于多种原因很难将Python 2.x中的两个概念完全分开。
更多OT,当您想要接收第三方HTTP请求时,您不能完全依赖以百分比转义,utf-8编码的八位字节发送的URL:偶尔可能有%uxxxx
在那里逃避,并且至少firefox 2.x用于在可能的情况下将URL编码为latin-1,并且仅在必要时将utf-8编码为utf-8。
答案 2 :(得分:2)
你运气不好stdlib,urllib.quote不适用于unicode。如果你使用django,你可以使用django.utils.http.urlquote,它可以正常使用unicode