초보 개발자

flask 이미지 업로드 방식 1 static에 집어넣기 본문

AI 웹개발 트랙 - 내배캠/3주차

flask 이미지 업로드 방식 1 static에 집어넣기

taehyeki 2021. 12. 30. 23:12

 

 

URL.createObjectURL

먼저 이미지 파일을 선택하면 화면에 보이도록 해주는 방법에 대해서 알아보겠다.

#image-uploader는 <input type=file> 태그이다.

여기에 이벤트 리스너를 주어서 상태가 변했을 때 (파일을 선택했을 때 , 'change' 이벤트)

실제 서버에 존재 하지는 않고, 해당 브라우저에서만 사용가능한 URL. 즉, 브라우저 내에서 해당 파일(객체)를 임시로 사용하기 위한 URL을 만들어 준다. 그리고 그 URL을  preview(img 태그)의 src에 넣어주면 화면에 잘 출력이 된다.

 

그리고 url을 사용하면 revoke를 통해서 해제 시켜주어야 메모리에 누수가 생기지 않는다.

위 처럼 읽어드린 후 바로 URL을 해제해도 image 는 이미지 출력 및 사용에 문제 없다.

하지만 해제된 이후에는 더이상 사용할 수가 없다. 

혹시나 하고 사용해보았더니 기존 미리보기 된 업로드가 사라졌다.

 

<input type="file"> 은 .files 라는 것을 가지며, files는 File 객체의 콜렉션이다.그리고 File은 Blob을 확장해서 만들어진 것이다.즉 Blob을 쓸 수 있는 곳이라면 File을 쓸 수도 있다.

그럼 음악도 되지 않을까 라는 생각에 해보니 음악또한 잘 되는 것을 확인할 수 있었다.  아무튼!!

 

input type을 file로 하고 파일을 업로드 후 전송버튼을 누르고 값을 확인을 해보면 그 안에 자료가 숨어 있다.

console.log($('#file'))

하지만 이렇게 보이는데...배열에 하나 있다. 이 배열에는 수많은 값이 있다.

이 것도 일부분일 뿐이다. 무튼 여기에 files라는 것이 있다.

files의 첫번째 배열에 우리가 첨부한 파일이 들어가 있는 것을 확인할 수 있다.. 꼭꼭 숨어있다.

 

jquery 기준)  $('#file')[0].files[0] 이렇게 접근했다.

그 다음 FormData를 만들어 주었다. html에 form이 존재한다면 form의  Node나 jquery를 적어주면 되지만 지금은 form이 없기 때문에 그냥 해주었다. title_give라는 것에 이름을, file_give라는 것에 file을 넣어주자 file은 앞서 우리가 발견한 #('file')[0].files[0]을 통째로 넣어주었다. formdata는 윈도우에 있는 객체이다.

 

만약 form을 만들고 이런식으로 넣어주면 form에 작성된 전체 내용이 들어간다.

 

 

우리가 한 방식대로 한다면 필요한 것만 선택적으로 보낼 수 있게 된다.

 

 

 

 

 

key(앞) value(뒤)값을 지정해주고 알아서 문자열로 변환해준다.

append말고 set으로도 값을 정해줄 수 있지만 set은 기존 key가 있으면 그 key값을 모두 덮어씌워버린다.

 

form의 속성중 (파일 전송 시) 헤더의 enctype이 반드시 'multipart/form-data'형 이어여만 한다. 아니면 제대로 전송이 안된다.

 

하지만 지금처럼 ajax로 보낼때는 주의해야할 사항이 있다.

 

ajax로 multipart 방식으로 보낼 때, processData는 일반적으로 서버에 전달되는 data는 query String 형태로 전달되어 집니다. data 파라미터로 전달된 데이터는 jQuery 내부적으로 쿼리스트링으로 만들어 보내는데, 파일전송에는 이를 피해야함으로 false로 설정해줍니다.

 

contentType은 default 값이 "application/x-www-form = urlencoded; charset = UTF-8" 이므로, 보내줄 때

multipart/form-data로 전송해야 하기 때문에 false로 설정해줍니다.

 

jquery로 formdata를 보낼때 contentType과 processData는 그냥 false로 둔다고 생각하자

 

이렇게 서버에 보내면 

title은 보통때와 마찬가지로 담겨져 오는데 file_give는 안보인다??

ImmutableMultiDict([('title_give', 'ㅎㅎ')])

file은 

file = request.files['file_give']

여기안에 담겨져 있다.

 

file의 headers를 출력하면 file.headers 아래와 같다

name에는 담겨져온 이름 filename은 파일원래의 이름이 담긴 걸 알 수 있다. 아래는 file을 출력한 것이다.

이렇게 파일이 들어온 걸 알 수있다.

여기서 file.filename을 하면 저 image(1).png가 출력이 된다. 파일의 원래 이름을 가져올 수 있다.

여기서 확장자 명만 따오고 우리가 제목으로 적었던 것 뒤에 붙여주기만 하면 된다. 파일 이름은 중복이 될 수 있으니까 지금 날짜와 같이 적어주자.

 

이렇게 파일이름은 내가 정한이름-시간으로 정해주었다.

여기서 file.save의 인자에 경로를 지정해주면 그 경로에 파일이 저장된다.

파일 저장 경로 설정 (파일은 db가 아니라, 서버 컴퓨터 자체에 저장됨)

db에 파일이름을 저장해주자.

불러올때는 

img_info = db.camp.find_one({'title': title})
return render_template('showing.html', img_info=img_info)

img태그에서 statid(넣어준 폴더)/img_info.img(파일 이름) 으로 불러오기를 해주면 된다.