背景
前端使用jQuery DataTables控件向后端发起ajax请求,后端使用Flask框架解析请求参数遇到的问题。请求参数如下图:
后端获取参数
from flask import Flask, request
print request.query_string
'draw=1&columns%5B0%5D%5Bdata%5D=name&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=true&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=position&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=true&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=office&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=true&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=age&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=true&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B4%5D%5Bdata%5D=start_date&columns%5B4%5D%5Bname%5D=&columns%5B4%5D%5Bsearchable%5D=true&columns%5B4%5D%5Borderable%5D=true&columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B5%5D%5Bdata%5D=salary&columns%5B5%5D%5Bname%5D=&columns%5B5%5D%5Bsearchable%5D=true&columns%5B5%5D%5Borderable%5D=true&columns%5B5%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B5%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=asc&start=0&length=20&search%5Bvalue%5D=&search%5Bregex%5D=false&name=%E5%BC%A0%E4%B8%89&_=1694594130375'
print request.values
CombinedMultiDict([ImmutableMultiDict([('draw', u'1'), ('columns[0][data]', u'name'), ('columns[1][name]', u''), ('columns[5][searchable]', u'true'), ('columns[5][name]', u''), ('columns[4][search][regex]', u'false'), ('columns[1][orderable]', u'true'), ('columns[4][orderable]', u'true'), ('columns[5][orderable]', u'true'), ('columns[2][orderable]', u'true'), ('columns[4][name]', u''), ('order[0][dir]', u'asc'), ('columns[1][search][regex]', u'false'), ('columns[3][name]', u''), ('columns[0][search][value]', u''), ('columns[2][searchable]', u'true'), ('columns[3][search][regex]', u'false'), ('columns[0][search][regex]', u'false'), ('columns[5][data]', u'salary'), ('start', u'0'), ('columns[4][searchable]', u'true'), ('columns[0][searchable]', u'true'), ('columns[5][search][value]', u''), ('columns[3][searchable]', u'true'), ('columns[2][search][value]', u''), ('columns[2][search][regex]', u'false'), ('columns[1][data]', u'position'), ('columns[1][searchable]', u'true'), ('columns[5][search][regex]', u'false'), ('columns[0][orderable]', u'true'), ('columns[4][data]', u'start_date'), ('columns[0][name]', u''), ('columns[2][data]', u'office'), ('columns[3][data]', u'age'), ('search[value]', u''), ('columns[3][orderable]', u'true'), ('_', u'1694594130375'), ('columns[4][search][value]', u''), ('name', u'\u5f20\u4e09'), ('search[regex]', u'false'), ('columns[1][search][value]', u''), ('order[0][column]', u'0'), ('columns[2][name]', u''), ('length', u'20'), ('columns[3][search][value]', u'')]), ImmutableMultiDict([])])
print request.values.get('columns[0][data]')
u'name'
print request.values.get("draw", default=0, type=int)
1
print request.values.get('columns[1][name]')
u''
可以看到这种方法虽然可以获取到对应参数的值,但是很麻烦。如果遇到一些复杂的逻辑判断,这种方式显然就不适合了。
解决方案
pip 安装 querystring-parser 库
pip install querystring-parser
import json
from querystring_parser import parser
tmp = parser.parse(request.query_string)
print json.dumps(tmp, ensure_ascii=False, indent=4)
{
"search": {
"regex": "false",
"value": ""
},
"name": "张三",
"draw": "1",
"start": "0",
"length": "20",
"_": "1694594130375",
"order": {
"0": {
"column": "0",
"dir": "asc"
}
},
"columns": {
"0": {
"orderable": "true",
"search": {
"regex": "false",
"value": ""
},
"data": "name",
"name": "",
"searchable": "true"
},
"1": {
"orderable": "true",
"search": {
"regex": "false",
"value": ""
},
"data": "position",
"name": "",
"searchable": "true"
},
"2": {
"orderable": "true",
"search": {
"regex": "false",
"value": ""
},
"data": "office",
"name": "",
"searchable": "true"
},
"3": {
"orderable": "true",
"search": {
"regex": "false",
"value": ""
},
"data": "age",
"name": "",
"searchable": "true"
},
"4": {
"orderable": "true",
"search": {
"regex": "false",
"value": ""
},
"data": "start_date",
"name": "",
"searchable": "true"
},
"5": {
"orderable": "true",
"search": {
"regex": "false",
"value": ""
},
"data": "salary",
"name": "",
"searchable": "true"
}
}
}
另外
可以看到上面已经将 request 请求中的所有参数转成 json 格式,但是数组的部分也转成了 json,例如 order 和 columns 字段,里面的 key 是数组下标,并没有转成 json 数组。如果需要转成标准的 json 数组格式,需要添加以下参数 normalized=True(默认值是 false)。
tmp = parser.parse(request.query_string, normalized=True)
print json.dumps(tmp, ensure_ascii=False, indent=4)
{
"draw": "1",
"name": "张三",
"search": {
"regex": "false",
"value": ""
},
"start": "0",
"length": "20",
"columns": [
{
"orderable": "true",
"search": {
"regex": "false",
"value": ""
},
"data": "name",
"name": "",
"searchable": "true"
},
{
"orderable": "true",
"search": {
"regex": "false",
"value": ""
},
"data": "position",
"name": "",
"searchable": "true"
},
{
"orderable": "true",
"search": {
"regex": "false",
"value": ""
},
"data": "office",
"name": "",
"searchable": "true"
},
{
"orderable": "true",
"search": {
"regex": "false",
"value": ""
},
"data": "age",
"name": "",
"searchable": "true"
},
{
"orderable": "true",
"search": {
"regex": "false",
"value": ""
},
"data": "start_date",
"name": "",
"searchable": "true"
},
{
"orderable": "true",
"search": {
"regex": "false",
"value": ""
},
"data": "salary",
"name": "",
"searchable": "true"
}
],
"order": [
{
"column": "0",
"dir": "asc"
}
],
"_": "1694594130375"
}