簡體   English   中英

React 前端將圖像發送到 fastapi 后端

[英]React frontend sending image to fastapi backend

前端 = React,后端 = FastApi。 如何簡單地從前端發送圖像,並讓后端將其保存到本地磁盤? 我嘗試了不同的方法:在 object 中,在 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但結果相同......

----- [已解決]為簡單起見刪除 user_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>
  );
}

回復您的評論:是的,有一個簡單的 JS-Fastapi 片段示例,不久前我回答了它。

您無法訪問該文件的原因非常簡單:python 參數的命名必須與 formData object 的鍵匹配。

相反,您正在訪問原始請求,這沒有意義。

只需將您的 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

供參考

以下是我的答案的參考(實際查了一下,我回答了多個與該主題相關的問題,應該足以理解上傳文件時可能遇到的基本問題)

如何在沒有 UI(即 HTML)的情況下將文件(docx、doc、pdf 或 json)發送到 fastapi 並對其進行預測?

如何使用 JavaScript 和 FastAPI 上傳多個文件?

如何使用 fastapi 和 vue 上傳文件? 我收到錯誤無法處理 422

從 React 應用程序上傳 excel 文件到 FastAPI

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM