기본적으로 폼태그의 enctype을 지정하지 않을 경우 디폴트로
application/x-www-form-urlencoded
로 지정되기 때문에 파일을 전송하려면
반드시 enctype을 multipart/form-data로 지정해주어야 합니다.
그리고 GET 메소드는 이용할 수 없고 method도 POST를 이용해야 합니다.
<html>
<body>
<form action = "http://localhost:5000/fileupload" method = "POST"
enctype = "multipart/form-data">
<input type = "file" name = "file" />
<input type = "submit"/>
</form>
</body>
</html>
HTML폼을 이용하지 않고 POSTMAN에서도 바로 file upload를 테스트해볼 수 있습니다.
기존에는 request.json
을 이용해서 request의 데이터들을 그대로 받아서 이용했지만 파일을 불러올 때는 request.files['key']
을 이용해서 불러옵니다.
파일 이름을 가져오고 싶을 때는 file_object.filename
을 사용하면 됩니다.
파일을 업로드 시킬때는 file_objects.save("경로명", "파일명")
을 사용해서 업로드 시킵니다.
파일이 있는 경로를 url에 입력하면 해당 이미지를 볼 수있습니다.
플라스크를 거쳐 경로를 변경하고 싶을 때는
send_from_directory("경로", "파일명")
을 사용하면 해당 경로에 접근했을 때
파일을 웹 상에 띄워주게 됩니다.
파일 경로를 지정해주고 싶은 데 만약 각 회원의 아이디로 폴더를 구분해서 프로필 이미지를 업로드 시켜주고 싶을 때가 필요할것입니다.
이럴 경우 폴더를 미리 생성해두고 진행할 수도 없기 때문에
import os
os.makedirs(image_path, exist_ok=True)
os.makedirs
의 exists_ok
라는 옵션을 이용하면 만약 존재하지 않는 폴더의 경우는 생성시킨다는 뜻입니다.
그 전에는 werkzeug에서 import 했으나 werkzeug.utils에서 import로 변경되었음.
from werkzeug.utils import secure_filename
에서 secure_filename을 사용하는 이유는 보안상의 이유때문에 그렇습니다.
filename = "../../../../home/username/.bashrc"
위와 같은 filename을 설정했다고 생각해봅니다.
위의 filename을 secure_filename을 이용하면
>>> secure_filename("../../../../home/username/.bashrc")
'home_username_.bashrc'
다음과 같이 경로를 쉽게 알아내는 것을 방지해줍니다.
import os
from flask import Flask, request
from werkzeug.utils import secure_filename
app = Flask(__name__)
...
# 파일 업로드
@app.route('/fileupload', methods=['POST']
def file_upload():
file = request.files['file']
filename = secure_filename(file.filename)
os.makedirs(image_path, exists_ok=True)
file.save(os.path.join(image_path, filename)
return
...
검색해도 잘 안 나왔는데,, 너무 정리 잘 해주셔서 감사합니다ㅠㅠ