본문 바로가기

개발하자

빠른 API - Axios로 파일 업로드 - 잘못된 요청

반응형

빠른 API - Axios로 파일 업로드 - 잘못된 요청

클라이언트 코드:

!<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>

<form id="uploadForm" role="form" method="post" enctype=multipart/form-data>
    <input type="file" id="file" name="file" multiple>
    <input type=button value=Upload onclick="uploadFile()">
</form>

<script type="text/javascript">
function uploadFile() {
   var formData = new FormData();
    var imagefile = document.querySelector('#file');
    formData.append("images", imagefile.files);
    axios.post('http://127.0.0.1:8000/upload', formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
    })
}
</script>
</body>
</html>

서버 코드:

from fastapi import FastAPI, File, UploadFile, FastAPI
from typing import Optional, List
from fastapi.responses import FileResponse, HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.middleware.cors import CORSMiddleware

...

def save_file(filename, data):
    with open(filename, 'wb') as f:
        f.write(data)
        print('file saved')

@app.post("/upload")
async def upload(files: List[UploadFile] = File(...)):
    print(files)
    for file in files:
        contents = await file.read()
        save_file(file.filename, contents)
        print('file received')

    return {"Uploaded Filenames": [file.filename for file in files]}

다음 오류가 발생합니다.

 ←[32mINFO←[0m:     127.0.0.1:10406 - "←[1mPOST /upload HTTP/1.1←[0m" ←[31m400 Bad Request←[0m 

폼 액션을 통해 단일 파일을 업로드하려고 했는데 모두 잘 작동하지만 두 개의 파일을 업로드해야 합니다.




첫째, 파일이나 양식 데이터를 업로드할 때 엔드포인트/루트에 정의된 것과 동일한 양식 키를 사용해야 합니다. 당신의 경우, 그것은. 따라서 클라이언트 측에서는 대신 해당 키를 사용해야 합니다.

둘째, 여러 파일을 업로드하는 방법은 파일 배열(즉, 코드 내)을 반복하여 각 파일을 객체에 추가하는 것입니다.

셋째, Axios 버전의 일부 버그/변경 때문에 오류가 발생하는 것 같습니다. 다음은 최신 버전입니다. cdnjs의 최신 버전을 사용하면 문제가 해결됩니다.

또는 와 유사한 를 사용할 수 있습니다(아래 Axios 예제와 동일한 방법으로 파일 목록을 추가할 수 있습니다). Fetch API에서 서버에 파일을 업로드할 때 설명대로 요청의 헤더를 명시적으로 설정합니다.

Axios를 사용한 작업 예:

<!DOCTYPE html>
<html>
   <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>Upload Files</title>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.27.2/axios.min.js"></script>   
   </head>
   <body>
      <input type="file" id="fileInput" multiple><br>
      <input type="button" value="Upload" onclick="uploadFile()">
      <script type="text/javascript">
         function uploadFile() {
             var fileInput = document.querySelector('#fileInput'); 
         
             if (fileInput.files[0]) {
                var formData = new FormData();
                for (const file of fileInput.files)
                    formData.append('files', file);

                 axios({
                         method: 'post',
                         url: '/upload',
                         data: formData,
                         headers: {
                             'Accept': 'application/json',
                             'Content-Type': 'multipart/form-data'
                         }
                     })
                    .then(response => {
                        console.log(response);
                    })
                    .catch(error => {
                        console.error(error);
                    });
             }
         }
      </script>
   </body>
</html>



Axios v 0.27.2부터는 다음을 수행할 수 있습니다.

axios
    .postForm("https://httpbin.org/post", document.querySelector("#fileInput").files)

모든 파일은 키와 함께 제출될 것입니다.

더 자세한 예:

    axios.postForm("https://httpbin.org/post", {
      "myField": "foo"
      "myJson{}": {x:1, y: 'bar'}, 
      "files[]": document.querySelector("#fileInput").files
    })

반응형