Flask 서버에 AJAX 및 jQuery를 사용하여 파일 업로드하는 방법을 정리합니다.
Flask 구조상 파일은 uploads 라는 폴더에 업로드 됩니다.
uploads 폴더가 있는지 확인이 필요합니다. 없으면 생성이 될 수 있도록 코드를 짜야되고요.
파일을 서버에 업로드하는 방법으로는 Form을 이용하여 제출 시 바로 전송하고 처리하는 방식도 있습니다만,
이 포스트에서는 AJAX를 이용해서 별도의 버튼을 클릭 시에 업로드될 수 있도록 하고, 전체 페이지를 새로고침 하지
Prerequisites
Python 3.7.4, Flask 1.1.1
Flask 애플리케이션 구성
Flask 프레임워크를 통해 애플리케이션을 구성합니다. 또한, 파일 업로드 위치와 사용자가 업로드할 수 있는 모든 파일의 최대 크기를 정의합니다.
보안상의 이유로 또는 서버 공간의 소모를 피하기 위해 사용자가 파일 크기에 제한 없이 업로드하도록 허용해서는 안 됩니다.
app.py 코드
from flask import Flask
UPLOAD_FOLDER = 'C:/uploads'
app = Flask(__name__)
app.secret_key = "secret key"
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
HTML 템플릿 생성
파일 업로드 페이지를 렌더링 하기 위해 templates 디렉터리 아래에index.html을 작성해야합니다.
Upload 버튼을 클릭한 후 FormData 파일 데이터를 저장하는 객체를 만듭니다.
먼저 파일 수를 검색하고 각 파일을 FormData 객체에 append 시켜서 저장합니다.
마지막으로 대상 디렉터리에 업로드하기 위해 서버 측 코드가 작성된 python-flask-files-upload url로 파일 데이터를 보냅니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
<!doctype html>
<html>
<head>
<title>Python Flask File(s) Upload Example</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function (e) {
$('#upload').on('click', function () {
var form_data = new FormData();
var ins = document.getElementById('multiFiles').files.length;
if(ins == 0) {
$('#msg').html('<span style="color:red">Select at least one file</span>');
return;
}
for (var x = 0; x < ins; x++) {
form_data.append("files[]", document.getElementById('multiFiles').files[x]);
}
$.ajax({
url: 'python-flask-files-upload', // point to server-side URL
dataType: 'json', // what to expect back from server
cache: false,
contentType: false,
processData: false,
data: form_data,
type: 'post',
success: function (response) { // display success response
$('#msg').html('');
$.each(response, function (key, data) {
if(key !== 'message') {
$('#msg').append(key + ' -> ' + data + '<br/>');
} else {
$('#msg').append(data + '<br/>');
}
})
},
error: function (response) {
$('#msg').html(response.message); // display error response
}
});
});
});
</script>
</head>
<body>
<h2>Python Flask File(s) Upload - Select file(s) to upload</h2>
<dl>
<p>
<p id="msg"></p>
<input type="file" id="multiFiles" name="files[]" multiple="multiple"/>
<button id="upload">Upload</button>
</p>
</dl>
</body>
|
cs |
파이썬 업로드 메인 함수
AJAX를 통해 넘어온 파일을 저장하는 함수를 작성해야 합니다.
성공 메시지 일 경우 다시 AJAX로 값을 넘겨주어야 합니다.
만약 허용되지 않은 파일이거나 오류가 발생할 경우, 오류 메시지를 전달하여 html에 표시합니다.
main.py 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | import os import urllib.request from app import app from flask import Flask, flash, request, redirect, render_template, jsonify from werkzeug.utils import secure_filename ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif']) def allowed_file(filename): return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS @app.route('/') def upload_form(): return render_template('file-upload.html') @app.route('/python-flask-files-upload', methods=['POST']) def upload_file(): # check if the post request has the file part if 'files[]' not in request.files: resp = jsonify({'message' : 'No file part in the request'}) resp.status_code = 400 return resp files = request.files.getlist('files[]') errors = {} success = False for file in files: if file and allowed_file(file.filename): filename = secure_filename(file.filename) file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) success = True else: errors[file.filename] = 'File type is not allowed' if success and errors: errors['message'] = 'File(s) successfully uploaded' resp = jsonify(errors) resp.status_code = 206 return resp if success: resp = jsonify({'message' : 'Files successfully uploaded'}) resp.status_code = 201 return resp else: resp = jsonify(errors) resp.status_code = 400 return resp if __name__ == "__main__": app.run() | cs |
Flask 애플리케이션 배포
python main.py서버를 실행합니다.
애플리케이션 테스트
홈페이지
브라우저에서 URL http://localhost:5000/ 을 누르면 이미지와 같이 출력이 표시됩니다.
- 파일을 아무것도 선택하지 않고 업로드 버튼을 누르는 경우
최소 하나라도 선택해야 된다고 표시
- 성공
전체 코드는 아래 링크 참고
https://github.com/Daewooki/Python/tree/main/python-flask-ajax-file-upload
GitHub - Daewooki/Python
Contribute to Daewooki/Python development by creating an account on GitHub.
github.com
'Python' 카테고리의 다른 글
[Python] Selenium과 Chrome driver를 활용한 Papago Translation 자동화 (0) | 2021.12.08 |
---|---|
[Python] 네이버 카페 게시글 크롤러(feat. 크롬 드라이버 & 셀레니움) (6) | 2021.11.23 |
[Python] 괄호 안에 문자 제거하기(정규식) (0) | 2021.11.15 |
[Python] 두 날짜 사이의 모든 날짜 구하기 (0) | 2021.09.29 |
[Python] flask jinja2에서 문자열 합치기 (0) | 2021.09.19 |
댓글