React前端将图像发送到fastapi后端

2024-09-23 22:25:23 发布

您现在位置:Python中文网/ 问答频道 /正文

前端=反应,后端=快速API。 如何从前端发送映像,并让后端将其保存到本地磁盘? 我尝试过不同的方法:在对象中,在base64字符串中,等等。 但我无法在FastApi中反序列化映像。 它看起来像一个编码的字符串,我试着将它写入一个文件,或对它进行解码,但没有成功

const [selectedFile, setSelectedFile] = useState(null);
const changeHandler = (event) => {setSelectedFile(event.target.files[0]);   };
const handleSubmit = event => {

const formData2 = new FormData();
formData2.append(
"file",
selectedFile,
selectedFile.name
);

const requestOptions = {
    method: 'POST',
    headers: { 'Content-Type': 'multipart/form-data' },
    body: formData2 // Also tried selectedFile
};
  fetch('http://0.0.0.0:8000/task/upload_image/'+user_id, requestOptions)
    .then(response => response.json())
}

return (  <div
            <form onSubmit={handleSubmit}>
              <fieldset>
                  <label htmlFor="image">upload picture</label><br/>
                  <input name="image" type="file" onChange={changeHandler} accept=".jpeg, .png, .jpg"/>

              </fieldset>
              <br/>
              <Button color="primary" type="submit">Save</Button>
            </form>
</div>
);

以及后端:

@router.post("/upload_image/{user_id}")
async def upload_image(user_id: int, request: Request):
    body = await request.body()
    
    # fails (TypeError)
    with open('/home/backend/test.png', 'wb') as fout:
        fout.writelines(body) 

我还试图简单地模仿客户机,如下所示: curl -F media=@/home/original.png http://0.0.0.0:8000/task/upload_image/3 但同样的结果

-[Solved]为了简单起见,删除用户id。 服务器部件必须如下所示:

@router.post("/uploadfile/")
async def create_upload_file(file: UploadFile = File(...)):
    out_path = 'example/path/file'
    async with aiofiles.open(out_path, 'wb') as out_file:
        content = await file.read()
        await out_file.write(content)

出于某种原因,客户端部分应该而不是在标题中包含内容类型:

function TestIt ( ) {
    const [selectedFile, setSelectedFile] = useState(null);
    const [isFilePicked, setIsFilePicked] = useState(false);
  
    const changeHandler = (event) => {
        setSelectedFile(event.target.files[0]);
        setIsFilePicked(true);
    };
    
    const handleSubmit = event => {
      event.preventDefault();
      const formData2 = new FormData();
      formData2.append(
        "file",
        selectedFile,
        selectedFile.name
      );
      
    const requestOptions = {
        method: 'POST',
        //headers: { 'Content-Type': 'multipart/form-data' }, // DO NOT INCLUDE HEADERS
        body: formData2
    };
      fetch('http://0.0.0.0:8000/task/uploadfile/', requestOptions)
        .then(response => response.json())
        .then(function (response) {
          console.log('response')
          console.log(response)
            });
    }
    return (  <div>
        <form onSubmit={handleSubmit}>
          <fieldset>
              <input name="image" type="file" onChange={changeHandler} accept=".jpeg, .png, .jpg"/>
          </fieldset>
          <Button type="submit">Save</Button>
        </form>
    </div>
  );
}

Tags: nameimageformeventresponsebodyfileupload
1条回答
网友
1楼 · 发布于 2024-09-23 22:25:23

回复您的评论:是的,有一个简单的JS Fastapi片段示例,不久前我已经回答了

无法访问该文件的原因相当简单:python参数的命名必须与formData对象的键匹配

相反,您正在访问原始请求,这是没有意义的

只需按如下方式更改python代码:

from fastapi import UploadFile, File

@router.post("/upload_image/{user_id}")
async def upload_image(user_id: int, file: UploadFile = File(...)):
    # Your code goes here

这在官方文件中有详细说明

https://fastapi.tiangolo.com/tutorial/request-files/?h=file

FYI

以下是我回答的参考资料(实际上,我回答了与此主题相关的多个问题,应该足以理解上传文件时可能遇到的基本问题)

How to send a file (docx, doc, pdf or json) to fastapi and predict on it without UI (i.e., HTML)?

How can I upload multiple files using JavaScript and FastAPI?

How to upload file using fastapi with vue? I got error unprocessable 422

Uploading an excel file to FastAPI from a React app

相关问题 更多 >