flask使用原生ajax不使用表单(Form)上传文件

Posted 罗兵の水库

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flask使用原生ajax不使用表单(Form)上传文件相关的知识,希望对你有一定的参考价值。

〇、知识点

jquery ajax 文档 告诉你可以使用默认的 application/x-www-form-urlencoded, multipart/form-data, or text/plain 这三种,其它的也可以,但是需要告诉ajax 的怎样序列化它。——这句话来源于:https://www.cnblogs.com/htoooth/p/7242217.html

 

一、原生ajax、不使用表单(Form)

app.py

import os
from flask import Flask, request, jsonify, render_template
from werkzeug import secure_filename

UPLOAD_FOLDER = \'uploads\'
ALLOWED_EXTENSIONS = set([\'txt\', \'pdf\', \'png\', \'jpg\', \'jpeg\', \'gif\'])

app = Flask(__name__)
app.config[\'UPLOAD_FOLDER\'] = UPLOAD_FOLDER


def allowed_file(filename):
    return \'.\' in filename and \\
           filename.rsplit(\'.\', 1)[1] in ALLOWED_EXTENSIONS

@app.route(\'/\')
def index():
    return render_template(\'index.html\')

@app.route(\'/uploadfile\', methods=[\'POST\'])
def upload_file():
    if request.method == \'POST\':
        print(\'request.files\', dir(request.files))
        file = request.files[\'file\']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            url = os.path.join(app.config[\'UPLOAD_FOLDER\'], filename)
            file.save(url)
            return jsonify(dict(url=url,)), 201

if __name__ == "__main__":
    app.run(debug=True)

 

index.html

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>Flask上传图片演示三</title>
</head>
<body>
    <h1>Flask上传本地图片示例三</h1>
    <p>不使用表单Form,原生javascript实现ajax,返回上传的图片所保存的位置</p>
    
    <input type="file" name="file" />
    <br>
    <input type="button" value="上传" />

    <p id="res"></p>
    <script>
    var file = document.querySelector(\'input[type="file"]\');
    var btn = document.querySelector(\'input[type="button"]\');
    
    //ajax
    btn.addEventListener(\'click\', function(event){
        event.preventDefault();
        
        var data = new FormData();
        data.append(file.name, file.files[0]);var xhr = new XMLHttpRequest();
        xhr.open(\'POST\', \'/uploadfile\', true);
        //xhr.setRequestHeader("Content-Type", "multipart\\/form-data;"); //千万不能要这一句,否则后台request.files读不到file
        xhr.send(data);
        
        xhr.addEventListener(\'loadend\', function(){
            if(xhr.status == 201){
                var res_json = JSON.parse(xhr.responseText);
                document.querySelector(\'#res\').innerHTML = "上传的图片保存在:" + res_json.url;
            }
        }, false);
    }, false);
    </script>
</body>
</html>

 

二、原生ajax、使用表单(Form)

app.py

import os
from flask import Flask, request, jsonify, render_template
from werkzeug import secure_filename

UPLOAD_FOLDER = \'uploads\'
ALLOWED_EXTENSIONS = set([\'txt\', \'pdf\', \'png\', \'jpg\', \'jpeg\', \'gif\'])

app = Flask(__name__)
app.config[\'UPLOAD_FOLDER\'] = UPLOAD_FOLDER


def allowed_file(filename):
    return \'.\' in filename and \\
           filename.rsplit(\'.\', 1)[1] in ALLOWED_EXTENSIONS

@app.route(\'/\')
def index():
    return render_template(\'index.html\')

@app.route(\'/uploadfile\', methods=[\'POST\'])
def upload_file():
    if request.method == \'POST\':
        file = request.files[\'file\']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            url = os.path.join(app.config[\'UPLOAD_FOLDER\'], filename)
            file.save(url)
            return jsonify(dict(url=url,)), 201


if __name__ == "__main__":
    app.run(debug=True)

 

index.html

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>Flask上传图片演示二</title>
</head>
<body>
    <h1>Flask上传本地图片示例二</h1>
    <p>使用表单Form,原生javascript实现ajax,返回上传的图片所保存的位置</p>
    
    <!-- <form enctype=\'multipart/form-data\'> 注意:非必须指定enctype=\'multipart/form-data\' -->
    <form>
        <input type="file" name="file"/>
        <br>
        <input type="submit" value="上传"/>
    </form>
    
    <p id="res"></p>
    <script>
    var form = document.querySelector(\'form\');
    
    //ajax
    form.addEventListener(\'submit\', function(event){
        event.preventDefault();
        
        var xhr = new XMLHttpRequest();
        xhr.open(\'POST\', \'/uploadfile\', true);
        xhr.send(new FormData(form)); //注意:不需要设置Content-Type
        
        xhr.addEventListener(\'loadend\', function() {
            if(xhr.status == 201){
                var res_json = JSON.parse(xhr.responseText);
                document.querySelector(\'#res\').innerHTML = "上传的图片保存在:" + res_json.url;
            }
        }, false);
    }, false);
    </script>
</body>
</html>

 

三、无ajax、只使用表单(Form)

app.py

import os
from flask import Flask, request, redirect, url_for, render_template
from werkzeug import secure_filename

UPLOAD_FOLDER = \'uploads\'
ALLOWED_EXTENSIONS = set([\'txt\', \'pdf\', \'png\', \'jpg\', \'jpeg\', \'gif\'])

app = Flask(__name__)
app.config[\'UPLOAD_FOLDER\'] = UPLOAD_FOLDER


def allowed_file(filename):
    return \'.\' in filename and \\
           filename.rsplit(\'.\', 1)[1] in ALLOWED_EXTENSIONS

@app.route(\'/\')
def index():
    return render_template(\'index.html\')

@app.route(\'/uploadfile\', methods=[\'POST\'])
def upload_file():
    if request.method == \'POST\':
        file = request.files[\'file\']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config[\'UPLOAD_FOLDER\'], filename))
            return redirect(url_for(\'uploaded_file\', filename=filename))

from flask import send_from_directory
@app.route(\'/uploads/<filename>\')
def uploaded_file(filename):
    return send_from_directory(app.config[\'UPLOAD_FOLDER\'], filename)


if __name__ == "__main__":
    app.run(debug=True)

 

index.html

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>Flask上传图片演示一</title>
</head>
<body>
    <h1>Flask上传本地图片示例一</h1>
    <p>使用表单Form,无javascript,跳转显示上传的图片</p>
    
    <form action="/uploadfile" enctype=\'multipart/form-data\' method=\'POST\'> <!-- 注意:三个全指定action, enctype, method -->
        <input type="file" name="file" style="margin-top:20px;"/>
        <br>
        <input type="submit" value="上传" style="margin-top:15px;"/>
    </form>
</body>
</html>

 

四、预览、无Form、原生ajax

index.html

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>Flask上传图片演示四</title>
</head>
<body>
    <h1>Flask上传本地图片示例四</h1>
    <p>上传前预览图片,不使用表单Form,原生ajax,返回上传的图片所保存的位置</p>
    
    <img id="base64image" src="" style="max-height:150px;"/>
    <br />
    <input type="file" name="image" accept="image/gif,image/jpeg,image/jpg,image/png,image/svg"/>
    <br />
    <input type="button" value="上传"/>

    <p id="res"></p>
    
    <script>
    var base64image = document.querySelector(\'#base64image\');
    var fileElement = document.querySelector(\'input[type="file"]\');
    var btnElement = document.querySelector(\'input[type="button"]\');
    
    //预览
    fileElement.addEventListener(\'change\', function(event){
        if (!event.target.files || !event.target.files[0]) {
            return;
        }
        var reader = new FileReader();
        reader.readAsDataURL(event.target.files[0]);
        
        reader.addEventListener("load", function(e){
            base64image.src = e.target.result; //base64编码
        }, false); 
    },false);
    
    //ajax
    btnElement.addEventListener(\'click\', function(event){
        event.preventDefault();
        
        var data = new FormData(); 
        data.append(fileElement.name, fileElement.files[0]);  //添加图片信息
        
        var xhr = new XMLHttpRequest();
        xhr.open("post", "/uploadfile", true);//true即异步
        //xhr.setRequestHeader(\'Content-Type\', \'multipart/form-data\'); //千万别写这句!!
        xhr.send(data);
        
        xhr.addEventListener("loadend", function(event){
            if(xhr.status == 201){ // 201,去看app.py!!
                var res = JSON.parse(xhr.responseText);  //接收的是json数据
                console.log(res);
            }
        }, false); 
    },false);
    </script>
</body>
</html>

 

以上是关于flask使用原生ajax不使用表单(Form)上传文件的主要内容,如果未能解决你的问题,请参考以下文章

[JavaScript]_[初级]_[不使用JQuery原生Ajax提交表单文件并监听进度]

[JavaScript]_[初级]_[不使用JQuery原生Ajax提交表单文件并监听进度]

如何使用 Ajax 提交 Flask-WTF 表单

AJAX POST Flask WTForm 不刷新页面

Flask添加翻页功能(非sqlalchemy)

Flask:在另一个页面上使用WTForm,而不是渲染表单本身