JavaScript AJAX POST如何在JSON payload中传递查询字符串参数
Kendo MultiSelect 发送POST JSON请求携带查询参数实现方案
核心问题说明
使用Kendo MultiSelect组件通过AJAX POST请求搜索数据时,需要将用户输入的搜索词、预设过滤条件(含数组类型字段)正确放入请求payload,原有代码存在配置位置错误、参数未动态合并、数据未回传组件的问题,导致功能不生效。
原有实现代码如下:
var payload ={ "vFilters": [ { "field": "DistLocationIds", "values": [ "2787" ] }, { "field": "VdistLocationIds", "values": [] }, { "field": "createdByLocationLevelId", "values": [] }, { "field": "taskLevelId", "values": [ "118" ] } ], "rangeFilters": [ { "greaterThanOrEqual": "2022-06-11", "field": "startDate" }, { "lessThanOrEqual": "2022-07-11", "field": "endDate" } ], "sorts": [], "limit": 50, "q": "s" }; var new1 = new kendo.data.DataSource({ transport: { read: function(options) { $.ajax({ delay: 350, // wait 250 milliseconds before triggering the request url: "https://tasklist", type: "post", data: JSON.stringify(payload), dataType: 'json', contentType: "application/json" }); }, contentType: "application/json", beforeSend: function(req) { req.setRequestHeader('Authorization', "Bearer @Session.AuthToken~"); }, processResults: function (data) { var res = []; if(data && data.results){ for(var i = 0 ; i < data.results.length; i++) { res.push({id: data.results[i].objectId, text: data.results[i].title}); } } return { results: res } }, complete: function(){ } } }); $("#islTasks").kendoMultiSelect({ placeholder: "Select Tasks...", filter: "contains", autoBind: false, dataValueField: "objectId", dataTextField : "title", dataSource : new1 });
修复要点
- 所有AJAX回调(
beforeSend、请求成功/失败回调)需放在$.ajax配置对象内部,不能放在kendo transport根层级,否则不会执行 - 每次触发搜索时动态获取用户输入的查询值,合并到预设的payload对象中,不要写死payload的
q字段 - 请求完成后必须调用
options.success()将处理后的数据回传给Kendo DataSource,否则组件无法渲染返回结果 - 原生$.ajax不支持
delay配置,需手动实现防抖,避免用户快速输入时发送大量无效请求 - 只要正确设置
contentType: "application/json",通过JSON.stringify()序列化包含数组的payload时,数组结构会被正确保留,后端可以正常解析
修复后完整代码
// 防抖定时器标记 let searchTimer = null; // 预设基础过滤条件 const basePayload = { "vFilters": [ { "field": "DistLocationIds", "values": ["2787"] }, { "field": "VdistLocationIds", "values": [] }, { "field": "createdByLocationLevelId", "values": [] }, { "field": "taskLevelId", "values": ["118"] } ], "rangeFilters": [ { "greaterThanOrEqual": "2022-06-11", "field": "startDate" }, { "lessThanOrEqual": "2022-07-11", "field": "endDate" } ], "sorts": [], "limit": 50 }; const taskDataSource = new kendo.data.DataSource({ transport: { read: function(options) { // 清除上一次未发送的请求,实现350ms防抖 if (searchTimer) clearTimeout(searchTimer); searchTimer = setTimeout(() => { // 动态合并用户输入的搜索关键词到payload const requestPayload = { ...basePayload, // 从组件传入的参数中获取用户输入的搜索值,无输入时传空字符串 q: options.data.filter?.filters?.[0]?.value || "" }; $.ajax({ url: "https://tasklist", type: "post", data: JSON.stringify(requestPayload), dataType: 'json', contentType: "application/json", beforeSend: function(req) { req.setRequestHeader('Authorization', "Bearer @Session.AuthToken~"); }, success: function (data) { const res = []; if(data && data.results){ for(let i = 0 ; i < data.results.length; i++) { res.push({ objectId: data.results[i].objectId, title: data.results[i].title }); } } // 将处理后的数据回传给DataSource options.success(res); }, error: function(err) { options.error(err); } }); }, 350); } } }); $("#islTasks").kendoMultiSelect({ placeholder: "Select Tasks...", filter: "contains", autoBind: false, dataValueField: "objectId", dataTextField : "title", dataSource : taskDataSource, minLength: 1 // 输入至少1个字符再触发搜索,减少无效请求 });
如果需要动态修改基础过滤条件(比如其他筛选项变化后更新vFilters的values),直接修改
basePayload对应字段的值即可,下一次搜索触发时会自动带上最新的参数。
内容的提问来源于stack exchange,提问作者Anvita Rastogi
相关产品推荐
相关产品推荐

