React摄像头捕获图片无法上传至Flask服务器求助
问题:React摄像头捕获图片无法上传至Flask服务器,本地上传正常
问题核心
摄像头实时捕获的图片发送到Flask后端时,服务器触发if 'file' not in request.files判断,返回"no file found"错误,但本地文件上传功能完全正常。
错误原因
摄像头组件中,你用context.getImageData().data获取了像素数组(Uint8ClampedArray类型)并添加到FormData,而Flask的request.files只能识别符合文件格式的对象(比如File、Blob)。本地上传组件直接使用input获取的File对象,所以能被正常解析。
修复方案
将canvas中的内容转换为Blob对象,再添加到FormData中,这样就能和本地上传的文件格式保持一致,让Flask正确识别。
修改后的React摄像头组件代码
"use client"; import "./myscript.css" import { useEffect, useRef } from 'react'; const MyWebcam = () => { const videoRef = useRef(null); useEffect(() => { const getUserMedia = async () => { try { const stream = await navigator.mediaDevices.getUserMedia({ video: true }); if (videoRef.current) { videoRef.current.srcObject = stream; videoRef.current.addEventListener('loadedmetadata', () => {}) } } catch (error) { console.error(error); } }; getUserMedia(); }, []); const takePicture = async () => { if (!videoRef.current || !videoRef.current.videoWidth || !videoRef.current.videoHeight) { console.log(videoRef.current) console.error('Video not ready'); } else{ const canvas = document.createElement('canvas'); canvas.width = videoRef.current.videoWidth; canvas.height = videoRef.current.videoHeight; const context = canvas.getContext('2d'); context.drawImage(videoRef.current, 0, 0, canvas.width, canvas.height); const imgUrl = canvas.toDataURL('image/png'); const img= document.getElementById("picture") img.src = imgUrl // 关键修改:将canvas转为Blob对象 canvas.toBlob(async (blob) => { const formData = new FormData() // 添加Blob到FormData,指定文件名和类型 formData.append('file', blob, 'captured-image.png') console.log("pre JSON fetching") console.log(formData) try { const response = await fetch("http://localhost:8080/results", { method: 'POST', body: formData }); console.log(response) const data = await response.json(); console.log('Response:', data); let ex = document.getElementById("translation") ex.textContent = data.message } catch(error){ console.error(error) } }, 'image/png'); // 指定图片格式为PNG } } return ( <div className="fullscreen-container"> <div className="input-div"> <h2>Video Capture</h2> <div className="video-container"> <video ref={videoRef} autoPlay width="900" height="900" /> <div className="image-container"> <img id="picture" width="900" height="900" alt="Captured" /> </div> </div> <button type="button" onClick={takePicture}>Take Picture</button> <p id="translation">Translation</p> </div> </div> ); }; export default MyWebcam;
关键修改点
- 使用
canvas.toBlob()方法将canvas内容转为Blob对象,这是异步操作,所以后续的fetch需要放在回调函数内 - 调用
formData.append('file', blob, 'captured-image.png')时,指定文件名(可选,但有助于后端识别文件类型) - 移除了之前的
context.getImageData()相关代码,改用Blob对象替代
这样修改后,Flask后端就能通过request.files['file']正确获取到图片文件,和本地上传的处理逻辑完全兼容,无需修改后端代码。
内容的提问来源于stack exchange,提问作者Bradan Craig
相关产品推荐
相关产品推荐

