• 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>
  • 相关阅读:
    Linux中配置别名
    Linux下的IO监控与分析
    RHEL6 Systemtap 安装笔记
    记一次多事件绑定中自己给自己设置的坑——click,dblclick,mousedown,mousemove,mouseup
    springboot打jar获取不到static静态资源文件问题
    关于springboot默认日志框架Slf4j+logback,自定义Appender问题
    spring 时间格式问题
    springboot 部署到tomcat,获取根路径问题。空格变为%20
    前后端分离 vue+springboot 跨域 session+cookie失效问题
    springboot 部署到tomcat中,项目总是重新部署
  • 原文地址:https://www.cnblogs.com/hhh5460/p/10228378.html
Copyright © 2020-2023  润新知