Tornado RequestHandler获取参数前如何解码URL编码查询串
Tornado URL编码场景下的参数读取方案
问题根因
该参数解析异常由两个问题共同导致:
- 路由正则配置错误
- 上游传参的URL编码逻辑不符合规范,并非Tornado自带的参数解析方法没有自动解码能力。
第一步:修正路由配置
当前路由规则r"?"是错误的正则写法:?是正则特殊量词,不能直接作为路径匹配规则使用,匹配根路径的正确配置如下:
handlers = [ (r"/", MainHandler) ]
第二步:按传参场景选择参数读取方式
场景1:符合URL标准规范的传参
标准URL查询串格式为key1=value1&key2=value2,其中&、=是参数分隔保留字符,仅当参数名/参数值本身包含这两个字符时,才需要对参数内部的特殊字符做URL编码。
举个例子:如果需要传递text参数值为Hi&lang=en,正确的查询串应该是text=Hi%26lang%3Den&lang=zh,这种场景下直接使用Tornado自带方法即可,框架会自动完成URL解码,不需要额外处理:
class MainHandler(RequestHandler): def get(self): args = { # 直接调用实例方法即可,不需要显式传入self "text": self.get_argument("text", default=""), "lang": self.get_argument("lang", default=""), } # 业务处理逻辑 # ......
注:原代码中RequestHandler.get_argument(self, "text", default="")属于冗余写法,直接调用实例方法self.get_argument()即可。
场景2:上游将整个查询串整体编码(当前遇到的情况)
查询串text%3DHi%26lang%3Den是把完整的text=Hi&lang=en整段做了URL编码的结果,属于上游传参逻辑错误。如果无法推动上游修正传参逻辑,可以手动对原始查询串做解码后再解析参数:
from urllib.parse import parse_qs, unquote class MainHandler(RequestHandler): def get(self): # 读取原始未解析的查询串 raw_query = self.request.query # 先做一次整体URL解码 decoded_query = unquote(raw_query) # 解析解码后的查询串为参数字典 parsed_params = parse_qs(decoded_query) args = { "text": parsed_params.get("text", [""])[0], "lang": parsed_params.get("lang", [""])[0] } # 业务处理逻辑 # ......
注意:如果上游传参符合规范,不要手动重复解码,否则会把参数值内部合法编码的%26、%3D错误解析为参数分隔符,导致参数错乱。
内容的提问来源于stack exchange,提问作者tejeshwar
相关产品推荐
相关产品推荐

