使用WebcamJS捕获图像后,无法通过XMLHttpRequest上传至Flask服务器求助
我来帮你搞定这个问题!你遇到的核心问题应该是WebcamJS捕获的base64图像数据没有正确转换成Flask能识别的文件格式,或者FormData的构建、XHR的配置有疏漏。下面是完整的解决方案,分前端和后端两部分:
前端完整代码(signup.html)
首先补全你的页面,加上WebcamJS的初始化、图像捕获和XHR提交逻辑:
<!DOCTYPE html> <html> <head> <title>Signup with Webcam</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/webcamjs/1.0.25/webcam.min.js"></script> </head> <body> <form method="POST" enctype="multipart/form-data" id="myForm"> <table> <tr> <td>Name/EmailId</td> <td>: <input type="text" name="userID" id="userID"></td> </tr> <tr> <td>Webcam Preview</td> <td><div id="my_camera" style="width:320px; height:240px;"></div></td> </tr> <tr> <td><input type="button" value="Capture Image" onclick="captureImage()"></td> <td><input type="button" value="Submit Form" onclick="submitForm()"></td> </tr> </table> <div id="results" style="display:none;">Captured Image:<br><img id="captured_img"></div> </form> <script> // 初始化WebcamJS配置 Webcam.set({ width: 320, height: 240, image_format: 'jpeg', jpeg_quality: 90 }); Webcam.attach('#my_camera'); let capturedImageData = null; // 捕获图像并保存base64数据 function captureImage() { Webcam.snap(function(data_uri) { document.getElementById('results').style.display = 'block'; document.getElementById('captured_img').src = data_uri; capturedImageData = data_uri; }); } // 用XHR提交表单和图像 function submitForm() { if (!capturedImageData) { alert('请先捕获图像!'); return; } // 构建FormData对象,包含表单字段和图像 const formData = new FormData(); formData.append('userID', document.getElementById('userID').value); // 把base64图像转成Blob,这是关键! const imageBlob = dataURItoBlob(capturedImageData); formData.append('webcam_image', imageBlob, 'captured_profile.jpg'); // 配置并发送XHR const xhr = new XMLHttpRequest(); xhr.open('POST', '/submit-signup', true); xhr.onload = function() { if (xhr.status === 200) { const res = JSON.parse(xhr.responseText); alert(`提交成功!${res.message}`); } else { alert(`提交失败,状态码:${xhr.status}`); } }; xhr.onerror = function() { alert('网络出错啦,请重试!'); }; xhr.send(formData); } // 辅助函数:将base64 Data URI转为Blob对象 function dataURItoBlob(dataURI) { const byteString = atob(dataURI.split(',')[1]); const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; const ab = new ArrayBuffer(byteString.length); const ia = new Uint8Array(ab); for (let i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } return new Blob([ab], { type: mimeString }); } </script> </body> </html>
Flask后端代码
然后是后端接收请求的逻辑,注意区分表单数据和上传文件:
from flask import Flask, request, jsonify import os app = Flask(__name__) # 创建uploads目录用于保存图像 UPLOAD_DIR = 'uploads' if not os.path.exists(UPLOAD_DIR): os.makedirs(UPLOAD_DIR) @app.route('/submit-signup', methods=['POST']) def handle_signup(): # 获取普通表单字段userID user_id = request.form.get('userID') if not user_id: return jsonify({'message': '请填写用户ID!'}), 400 # 获取上传的摄像头图像 webcam_img = request.files.get('webcam_image') if not webcam_img or webcam_img.filename == '': return jsonify({'message': '请先捕获图像!'}), 400 # 保存图像到本地 save_path = os.path.join(UPLOAD_DIR, f'{user_id}_profile.jpg') webcam_img.save(save_path) # 这里可以添加你的业务逻辑,比如存入数据库等 return jsonify({'message': f'用户{user_id}的资料已提交成功!'}) if __name__ == '__main__': app.run(debug=True)
关键注意事项
- 图像格式转换:WebcamJS返回的是base64字符串,必须转成Blob才能被FormData识别为文件,这是很多人踩坑的点。
- FormData的使用:不需要手动设置
Content-Type,浏览器会自动为FormData添加正确的multipart/form-data请求头(包含boundary)。 - 后端数据获取:Flask中用
request.form拿普通表单数据,request.files拿上传的文件,两者不能搞混。 - 目录权限:确保Flask有权限写入uploads目录,否则保存图像会失败。
内容的提问来源于stack exchange,提问作者Sunil
相关产品推荐
相关产品推荐

