포시코딩

Flask + JS, Ajax 파일 업로드 및 데이터 전송 본문

Python/Flask

Flask + JS, Ajax 파일 업로드 및 데이터 전송

포시 2022. 12. 6. 23:26
728x90

개요

회원가입에서 회원정보와 이미지파일을 같이 전달하기 위해 방법을 찾다가

정보도 너무 없고 그나마 있는 정보들도 중구난방식이라 오랜 시간에 걸쳐 방법을 찾은 후 정리를 위해 포스팅함

 

잘못된 시도

<input type="file" id="input_file">
<button onclick="test()" type="button" class="btn btn-primary">저장</button>
function test() {
  let file = document.querySelector('#input_file').files;

  let data = new FormData();
  data.append('file', file);

  $.ajax({
    type: "POST",
    url: '/file',
    data: data,
    processData: false,
    contentType: false,
    success: (res) => {
      console.log(res);
    }
  });
}
@app.route('/file', methods=['POST'])
def file_post():
  print(request.form)

  return jsonify({'msg': False})

file input 태그를 만들어 거기에 이미지를 넣고나서 ajax통신으로 서버에 보냈을 때, 

사진과 같이 ImmutableMultiDict가 뜨는것까지 확인을 했다. 

내가 보낸 key이름인 file로도 지정되어 있고 그 안의 object FileList만 꺼내면 되는줄 알았다.

하지만..

 

무슨짓을 해도 저 값을 확인할 수 없었고

애초에 찾는 글마다 모두 requset.form 대신 requset.files를 통해 이미지 파일 정보를 받아오고 있었다.

 

그래서 나도 print(requset.form) 밑에 print(request.files)를 찍어봤지만 

@app.route('/file', methods=['POST'])
def file_post():
  print(request.form)
  print(request.files)

  return jsonify({'msg': False})

아무것도 반환하고 있지 않았다. 

아예 없다.

 

문제 해결

답은 file input 데이터를 보내는게 아니라 form을 만들어 그 안에 모든 값들을 담은 후

new FormData() 를 통해 통째로 보내는 것이었다.

<form id="file_form">
  <input type="text" class="form-control" name="title" value="qwer">
  <input type="text" class="form-control" name="name" value="1234">
  <input type="file" id="input_file" name="input_file">  
  <!-- 꼭!!! 전달할 input에 name을 지정해줘야 form 데이터로 넘겼을 때 확인할 수 있다. -->
  <button onclick="test()" type="button" class="btn btn-primary">저장</button>
</form>
function test() {
  const input_file = document.querySelector('#file_form');
  // const input_file = $('#file_form')[0];  // jQuery 사용시에는 이렇게 [0]을 붙어줘야한다.
  let data = new FormData(input_file);
  
  $.ajax({
    type: "POST",
    url: '/file',
    data: data,
    contentType: false, 
    processData: false, 
    success: (res) => {
      console.log(res);
    }
  });
}
@app.route('/file', methods=['POST'])
def file_post():
  print(request.form)
  print(request.files)

  return jsonify({'msg': False})

보면 수많은 구글에 있던 글처럼 request.files를 통해 이미지 데이터를 받는걸 확인할 수 있다.

그와 동시에 request.form으로 다른 input type이 text인 값들도 받는걸 확인할 수 있는데

이를 통해 file 데이터와 text 데이터를 같이 받아 처리할 수 있는 상황이 만들어졌다.

 

여기까지 html에서 javascript를 통해 Flask 서버로 받는 과정에 대해 알아보았다.

그 이후의 작업은 목적에 따라 다양해지니 그에 맞는 방법을 찾아 구현하도록 하자!

728x90