jQuery Ajax提交大体积数据时接口不调用、请求实体过大报错
问题现象
提交小体积字符串数据时,后端接口可正常调用;提交大体积字符串数据时,触发Method not allowed(方法不允许)异常,偶发request entity too large(请求实体过大)错误。已尝试调大服务端内存限制与POST请求最大尺寸限制,问题未解决。
对应前端实现代码:
$("#Exceldownload_jobAlloctn").click(function(){ var getrowdata = $('#location_grid_for_hub').jqxGrid('getrows'); var getrowdata = JSON.stringify(getrowdata); if($('#location_grid_for_hub').jqxGrid('getrows').length == 0) { callnotify_alert("Error","No Data to Export",'danger'); return false; } else{ $.ajax({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }, url: "/Exportdata", dataType: 'text', type: "POST", processData: true, data: {"grid_data":getrowdata }, error: function (error) { console.log(error); }, success: function (data) { console.log(data); var excel_nm= data; var link1 = document.createElement("a"); document.body.appendChild(link1); link1.download = data; link1.title = data; link1.setAttribute("type", "hidden"); link1.setAttribute("download", data); var url=$("#excelfile_url").val(); link1.href = url+excel_nm; link1.click(); document.body.removeChild(link1); } }); } });
问题排查与修复方案
- 报错逻辑说明:偶发的
request entity too large是请求体超限的直接报错,固定出现的Method not allowed本质是超限请求被链路中的某一层拦截后,重定向到了仅支持GET方法的错误页,并非接口本身未注册POST方法。 - 全链路请求大小限制排查:仅调整应用层的内存、POST大小限制不足以解决问题,请求经过的所有节点都有独立的请求体大小阈值,需逐层调整:
- 如果部署架构用了Nginx等反向代理,默认
client_max_body_size值仅为1M,大体积提交很容易触发拦截,需要在对应站点的Nginx配置中调大该值,修改后重载Nginx配置生效:server { # 其余站点配置省略 client_max_body_size 100M; # 按实际业务传输的最大数据量调整数值 } - 从代码中的CSRF令牌写法判断,后端是Laravel框架(PHP技术栈),除了
php.ini中的post_max_size、memory_limit参数,还要同步检查php-fpm配置中的请求大小限制、Laravel默认ValidatePostSize中间件的阈值配置,修改后重启php-fpm服务才会生效。 - 如果服务器开启了WAF防护,检查是否有大体积POST请求拦截规则,这类规则拦截请求后跳转错误页,同样会返回405状态码。
- 如果部署架构用了Nginx等反向代理,默认
- 前端传输优化:当前AJAX请求未显式指定
contentType,jQuery默认以application/x-www-form-urlencoded格式传输,JSON字符串做表单URL编码时会对特殊字符转义,额外增加30%左右的传输体积,建议改为JSON格式提交降低传输开销,修改后的AJAX核心配置如下:
注意修改前端提交格式后,后端接口取参逻辑要对应调整,从读取表单POST参数改为解析JSON请求体获取$.ajax({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }, url: "/Exportdata", dataType: 'text', type: "POST", processData: true, contentType: "application/json; charset=utf-8", // 显式指定JSON提交格式 data: JSON.stringify({grid_data: getrowdata}), // 直接序列化整个提交对象 error: function (error) { console.log(error); }, success: function (data) { console.log(data); var excel_nm= data; var link1 = document.createElement("a"); document.body.appendChild(link1); link1.download = data; link1.title = data; link1.setAttribute("type", "hidden"); var url=$("#excelfile_url").val(); link1.href = url+excel_nm; link1.click(); document.body.removeChild(link1); } });grid_data字段即可。
内容的提问来源于stack exchange,提问作者Aram
相关产品推荐
相关产品推荐

