如何在不更改页面的情况下上传文件

Posted

技术标签:

【中文标题】如何在不更改页面的情况下上传文件【英文标题】:How to upload a file without changing the page 【发布时间】:2018-09-11 11:31:36 【问题描述】:

我想在服务器上上传一个文件并对该文件执行操作。我正在使用Flask 呈现一个模板,该模板显示一个表单以选择文件并使用发布操作上传。我还使用websockets 在服务器和客户端之间进行通信。我想做的是:

    显示 index.html 用户选择文件 点击提交按钮 文件已上传,但 url 没有改变,即它仍然显示 index.html (它重定向到 /uploads) 使用 websocket 更改状态

目前,正在发生的事情是 python upload_file 函数要求我返回类似“文件上传成功”之类的内容,这正在改变视图。如果我从那里重定向到 index.html,则会创建一个新会话。(我可能在这里错了)

index.html 的内容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Flask SocketIO Test</title>
</head>
<body>
<p>Anacall</p>

<form action="/upload" method="POST"
      enctype="multipart/form-data">
    <input type="file" name="file"/>
    <input type="submit"/>
</form>

<br>
<p id="status">Status</p>

<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
<script type="text/javascript" charset="utf-8">
        var socket = io.connect('http://' + document.domain + ':' + location.port);

         socket.on('connect', function() 
            socket.emit('get_status')
            console.log('Websocket connected!');
            );

        socket.on('response_status',function()
        document.getElementById("status").innerHTML = "Status : File Status";
        console.log("response received");
    );



</script>
</body>
</html>

python文件内容:

from flask import Flask, render_template, request, redirect, url_for
from flask_socketio import SocketIO, emit
from werkzeug import secure_filename

app = Flask(__name__)
socketio = SocketIO(app)

UPLOAD_FOLDER = '/static'
ALLOWED_EXTENSIONS = set(['xlsx', 'txt'])

status = None


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


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


@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            return 'No file selected'
        file = request.files['file']
        if file.filename == '':
            return "No file selected"
        if file and allowed_file(file.filename):
            file.save(secure_filename("file.xlsx"))  # saves in current directory
            status = "File uploaded"

    return redirect(url_for('index'))


@socketio.on('get_status')
def send_status():
    print("Send status now")
    if (status != None):
        emit("response_status")


if __name__ == '__main__':
    socketio.run(app, host='10.131.65.115', port=12000)

【问题讨论】:

【参考方案1】:

你是对的。每次重新加载页面时,WebSocket 连接都会关闭并再次重新打开。要摆脱这种情况,您必须使用 session-cookies 等对会话进行身份验证。

但您可以在 python 文件的 upload_file-Method 中编写 return ('', 204)。这告诉客户端(浏览器)没有内容。 “上传”操作可以在 iFrame 中实现。

但我建议您使用DropzoneJS。

Flask 示例:

https://github.com/greyli/flask-dropzone https://github.com/helloflask/flask-upload-dropzone

【讨论】:

对不起,我忘了告诉,我也试过 return('',204) 方法,但它返回空白页。网页中没有显示任何内容。(尚未尝试 IFrame 方法)。将研究 DropzoneJS,感谢您的建议。

以上是关于如何在不更改页面的情况下上传文件的主要内容,如果未能解决你的问题,请参考以下文章

在不刷新页面的情况下以表单上传文件

如何在不刷新整个页面的情况下更新 HTML 文档中的 php 变量?

如何允许用户在不登录的情况下使用 Google Form 上传文件?

Node.js:如何在不上传文件列表的情况下检查文件夹是不是为空

如何在不使用 Firebase 身份验证的情况下保护 Firebase 存储? (下一个)

如何在不写入文件的情况下压缩流并将其上传到 Azure Blob 存储?