假设我使用 JavaScript 发送请求:
fetch("/query?q=" + encodeURIComponent("c'est un château? Yes & no!"));
到 Python Bottle 服务器:
from bottle import Bottle, request
app = Bottle("")
@app.route("/query")
def query():
q = request.query.get("q") # how to decode it?
print(q)
app.run()
如何解码
request.query.get("q")
以便提取 encodeURIComponent
编码?在此示例中,?
和&
已正确解码,但â
未正确解码:print(q)
给出c'est un château? Yes & no!
_parse_qsl
def _parse_qsl(qs):
r = []
for pair in qs.split('&'):
if not pair: continue
nv = pair.split('=', 1)
if len(nv) != 2: nv.append('')
key = urlunquote(nv[0].replace('+', ' '))
value = urlunquote(nv[1].replace('+', ' '))
r.append((key, value))
return r
urlunquote
是 Python 2.x 中的 urllib.unquote
,或者是 urllib.parse.unquote
,其中 encoding
在 Python 3.x 中预设为 'latin1'
:
from urllib.parse import urlencode, quote as urlquote, unquote as urlunquote
urlunquote = functools.partial(urlunquote, encoding='latin1')
正是这种假设导致了您所看到的结果,而默认的
'utf8'
就可以工作:
>>> from urllib.parse import unquote
>>> quoted = "c'est%20un%20ch%C3%A2teau%3F%20Yes%20%26%20no!"
>>> unquote(quoted, encoding="latin1")
"c'est un château? Yes & no!"
>>> unquote(quoted)
"c'est un château? Yes & no!"
FormsDict
,其中属性访问或调用 getunicode
方法将为您提供 UTF-8 版本,而 get
方法和索引访问则提供 Latin-1:
>>> from bottle import FormsDict
>>> fd = FormsDict()
>>> fd["q"] = "c'est un château? Yes & no!"
>>> fd["q"]
"c'est un château? Yes & no!"
>>> fd.get("q")
"c'est un château? Yes & no!"
>>> fd.q
"c'est un château? Yes & no!"
>>> fd.getunicode("q")
"c'est un château? Yes & no!"
或者,您可以
decode
所有内容均为 UTF-8 的版本:
>>> utfd = fd.decode("utf8")
>>> utfd["q"]
"c'est un château? Yes & no!"
>>> utfd.get("q")
"c'est un château? Yes & no!"
>>> utfd.q
"c'est un château? Yes & no!"
>>> utfd.getunicode("q")
"c'est un château? Yes & no!"
这在文档中有所介绍:
除了正常的类似字典的项目访问方法(返回 未修改的数据作为本机字符串),[
] 还支持 对其值进行类似属性的访问。属性会自动分解 或重新编码以匹配FormsDict
(默认值:‘utf8’)。input_encoding