You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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)

关键注意事项

  1. 图像格式转换:WebcamJS返回的是base64字符串,必须转成Blob才能被FormData识别为文件,这是很多人踩坑的点。
  2. FormData的使用:不需要手动设置Content-Type,浏览器会自动为FormData添加正确的multipart/form-data请求头(包含boundary)。
  3. 后端数据获取:Flask中用request.form拿普通表单数据,request.files拿上传的文件,两者不能搞混。
  4. 目录权限:确保Flask有权限写入uploads目录,否则保存图像会失败。

内容的提问来源于stack exchange,提问作者Sunil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:54:47