JavaScript向Flask上传1MB以上文件失败,请教PUT/POST传查询字符串方法
大文件上传报错与Flask请求查询字符串传递问题
问题现象
小文件上传正常,但上传1MB以上大文件时出现异常:
- Chromium控制台报错:
Failed to load resource: net::ERR_CONNECTION_RESET - Firefox控制台报错:
NetworkError when attempting to fetch resource - 服务器返回
308状态码 - 生产服务器和Gunicorn环境下均存在此问题
最初的代码实现
JavaScript代码
let data = new FormData(); data.append("file", inputFile.files[0]); let response = await fetch("/upload?key=value", {method: "PUT", body: data});
Python/Flask代码
@app.put('/upload/') def upload_file(): key = request.args['key'] file = request.files['file'] print(key) print(file) return ''
编辑说明
已定位问题根源是URL中的查询字符串,移除后代码可正常运行。现需明确:如何在PUT或POST请求中向Flask传递查询字符串?
修改后的可正常运行代码
JavaScript代码
let data = new FormData(); data.append("file", inputFile.files[0]); let response = await fetch("/upload/", {method: "PUT", body: data});
Python/Flask代码
@app.put('/upload/') def upload_file(): file = request.files['file'] print(file) return ''
解决方案:PUT/POST请求传递查询字符串的正确方式
1. 修正路由匹配,保留URL查询字符串
你遇到的308重定向问题,本质是Flask路由规则的严格匹配导致:路由定义是/upload/(带末尾斜杠),但请求URL是/upload?key=value(不带末尾斜杠)。Flask会对这种不匹配的URL返回308永久重定向,而大文件上传时,浏览器不会在重定向请求中重新发送完整的FormData,进而引发连接重置。
解决方法二选一:
- 请求URL改为
/upload/?key=value(加上末尾斜杠),和路由定义完全匹配; - 把Flask路由改为
@app.put('/upload')(去掉末尾斜杠),和请求URL匹配。
修正后的JavaScript请求示例:
let response = await fetch("/upload/?key=value", {method: "PUT", body: data});
2. 其他参数传递方式(替代查询字符串)
如果不想用URL查询字符串,也可以用以下两种方式传递参数:
将参数放入FormData中
JavaScript代码:let data = new FormData(); data.append("file", inputFile.files[0]); data.append("key", "value"); // 把参数加到FormData里 let response = await fetch("/upload/", {method: "PUT", body: data});Flask中通过
request.form获取:@app.put('/upload/') def upload_file(): key = request.form.get('key') file = request.files['file'] print(key, file) return ''通过自定义请求头传递
JavaScript代码:let response = await fetch("/upload/", { method: "PUT", body: data, headers: { 'X-Custom-Key': 'value' // 自定义请求头携带参数 } });Flask中通过
request.headers获取:@app.put('/upload/') def upload_file(): key = request.headers.get('X-Custom-Key') file = request.files['file'] print(key, file) return ''
内容的提问来源于stack exchange,提问作者Dante
相关产品推荐
相关产品推荐

