如何使用JavaScript向Flask REST接口上传二进制图片数据
实现方案
1. 服务端补全必要配置
你现有服务端代码缺少跨域支持,且返回格式、异常处理不完善,先做调整:
先安装跨域依赖:pip install flask-cors
修正后的服务端代码:
from flask import Flask, request from flask_restful import Resource, Api from flask_cors import CORS import os app = Flask(__name__) # 开发环境放开跨域限制,生产环境需配置指定允许的来源域名 CORS(app) api = Api(app) # 提前创建图片存储目录,避免保存时路径报错 SAVE_DIR = "upload_imgs" if not os.path.exists(SAVE_DIR): os.makedirs(SAVE_DIR) class process_image(Resource): def post(self): if "image" not in request.files: return {"code":400, "msg":"未接收到图片文件"}, 400 file = request.files["image"] # 可自行修改命名规则,比如拼接时间戳避免重名覆盖 save_path = os.path.join(SAVE_DIR, "target_img.jpg") file.save(save_path) return {"code":200, "msg":"图片上传成功"}, 200 api.add_resource(process_image, "/image") if __name__ == "__main__": app.run(debug=True)
2. 前端HTML+AJAX实现
文件上传必须使用FormData对象包装传输,禁止手动设置Content-Type请求头,否则会丢失边界参数导致服务端解析失败,浏览器会自动生成符合规范的带boundary的请求头。
HTML部分:
<!-- 文件选择控件,仅接受图片格式 --> <input type="file" id="imgPicker" accept="image/*"> <button id="uploadBtn">上传图片</button> <p id="statusTip"></p>
原生JS(AJAX)逻辑:
const uploadBtn = document.getElementById("uploadBtn"); const imgPicker = document.getElementById("imgPicker"); const statusTip = document.getElementById("statusTip"); uploadBtn.addEventListener("click", () => { const selectedFile = imgPicker.files[0]; if (!selectedFile) { statusTip.innerText = "请先选择需要上传的图片"; return; } // 构造FormData,字段名必须和服务端request.files取的key一致,即"image" const fd = new FormData(); fd.append("image", selectedFile); const xhr = new XMLHttpRequest(); xhr.open("POST", "http://127.0.0.1:5000/image"); xhr.onload = () => { if (xhr.status === 200) { const res = JSON.parse(xhr.responseText); statusTip.innerText = res.msg; } else { statusTip.innerText = `上传失败,响应状态码:${xhr.status}`; } } xhr.onerror = () => { statusTip.innerText = "网络异常,请求发送失败"; } // 直接发送FormData即可,不要手动设置请求头 xhr.send(fd); })
常见踩坑说明
- 直接以
file://协议打开本地HTML文件发请求大概率触发跨域拦截,建议将前端页面放到Flask的templates目录下,通过Flask路由渲染访问,可彻底避免跨域问题 - FormData的字段名必须和服务端接收的key完全匹配,否则服务端无法读取到上传的文件
- 存储文件的目录必须提前创建,否则会触发路径不存在的报错
- 若使用jQuery等封装的AJAX方法,需注意关闭默认的参数序列化处理,比如jQuery要加
processData: false, contentType: false配置
内容的提问来源于stack exchange,提问作者Caminero
相关产品推荐
相关产品推荐

