Python Flask解析jQuery DataTables发送的ajax请求参数

背景

前端使用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"
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Amour_柒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值