2016-03-04 91 views
2

我无法重定向到main.demo。一切工作正常,直到没有发生重定向后的数据上传。为什么?无法重定向到烧瓶中的网址

编辑:app.py

from flask import Blueprint 
main = Blueprint('main', __name__) 
import json 
import os 
from flask import Flask, request,render_template,url_for,redirect 
from werkzeug import secure_filename 

import glob2 
from uuid import uuid4 



@main.route('/') 
def index(): 
    """Main index page """ 
    return render_template('index.html') 

@main.route('/upload', methods=["GET","POST"]) 
def upload(): 
    if request.method == 'POST': 
     form = request.form 
     # Create a unique "session ID" for this particular batch of uploads. 
     upload_key = str(uuid4()) 

     # Is the upload using Ajax, or a direct POST by the form? 
     is_ajax = False 
     if form.get("__ajax", None) == "true": 
      is_ajax = True 

     # Target folder for these uploads. 
     target = "upload/{}".format(upload_key) 
     try: 
      os.mkdir(target) 
     except: 
      if is_ajax: 
       return ajax_response(False, "Couldn't create upload directory: {}".format(target)) 
      else: 
       return "Couldn't create upload directory: {}".format(target) 

     print "=== Form Data ===" 
     for key, value in form.items(): 
      print key, "=>", value 

     for upload in request.files.getlist("file"): 
      filename = upload.filename.rsplit("/")[0] 
      destination = "/".join([target, filename]) 
      print "Accept incoming file:", filename 
      print "Save it to:", destination 
      upload.save(destination) 
     return redirect(url_for("main.demo")) 
    return render_template("upload.html") 


@main.route('/demo',methods=["GET","POST"]) 
def demo(): 
    if request.method == "GET": 
     return render_template("demo.html") 

def ajax_response(status, msg): 
    status_code = "ok" if status else "error" 
    return json.dumps(dict(
     status=status_code, 
     msg=msg, 
    )) 

def create_app(): 
    global app 
    app = Flask(__name__,template_folder=os.path.join(os.path.dirname(os.path.abspath(__file__)),'templates')) 
    app.debug = True 
    app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER 
    app.register_blueprint(main) 
    #app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 
    return app 

以下是其中一些我收到日志:

=== Form Data === 
__ajax => true 
Accept incoming file: demo.txt 
Save it to: upload/XXXXXXX-XXXXXX-XXXXX-XXXXXXX/demo.txt 
"POST /upload HTTP/1.1" 302 231 "http://localhost:5000/upload" 

"GET /demo HTTP/1.1" 200 3624 "http://localhost:5000/upload" 

它表明这是怎么回事了演示,但最后的网址是错误的。这是为什么?

编辑1:

是不是像我无法提交表单的页面不被刷新?但它被重定向到demo()函数执行它但不,但不render_template。或者它确实会以某种方式回到相同的功能?

编辑2:

更多以添加该代码使用在后台

// Constants 
var MAX_UPLOAD_FILE_SIZE = 1024*1024; // 1 MB 
var UPLOAD_URL = "/upload"; 
var NEXT_URL = "/demo"; 

// List of pending files to handle when the Upload button is finally clicked. 
var PENDING_FILES = []; 


$(document).ready(function() { 
    // Set up the drag/drop zone. 
    initDropbox(); 

    // Set up the handler for the file input box. 
    $("#file-picker").on("change", function() { 
     handleFiles(this.files); 
    }); 

    // Handle the submit button. 
    $("#upload-button").on("click", function(e) { 
     // If the user has JS disabled, none of this code is running but the 
     // file multi-upload input box should still work. In this case they'll 
     // just POST to the upload endpoint directly. However, with JS we'll do 
     // the POST using ajax and then redirect them ourself when done. 
     e.preventDefault(); 
     doUpload(); 
    }) 
}); 


function doUpload() { 
    $("#progress").show(); 
    var $progressBar = $("#progress-bar"); 

    // Gray out the form. 
    $("#upload-form :input").attr("disabled", "disabled"); 

    // Initialize the progress bar. 
    $progressBar.css({"width": "0%"}); 

    // Collect the form data. 
    fd = collectFormData(); 

    // Attach the files. 
    for (var i = 0, ie = PENDING_FILES.length; i < ie; i++) { 
     // Collect the other form data. 
     fd.append("file", PENDING_FILES[i]); 
    } 

    // Inform the back-end that we're doing this over ajax. 
    fd.append("__ajax", "true"); 

    var xhr = $.ajax({ 
     xhr: function() { 
      var xhrobj = $.ajaxSettings.xhr(); 
      if (xhrobj.upload) { 
       xhrobj.upload.addEventListener("progress", function(event) { 
        var percent = 0; 
        var position = event.loaded || event.position; 
        var total = event.total; 
        if (event.lengthComputable) { 
         percent = Math.ceil(position/total * 100); 
        } 

        // Set the progress bar. 
        $progressBar.css({"width": percent + "%"}); 
        $progressBar.text(percent + "%"); 
       }, false) 
      } 
      return xhrobj; 
     }, 
     url: UPLOAD_URL, 
     method: "POST", 
     contentType: false, 
     processData: false, 
     cache: false, 
     data: fd, 
     success: function(data) { 
      $progressBar.css({"width": "100%"}); 
      data = JSON.parse(data); 

      // How'd it go? 
      if (data.status === "error") { 
       // Uh-oh. 
       window.alert(data.msg); 
       $("#upload-form :input").removeAttr("disabled"); 
       return; 
      } 
      else { 
       // Ok! Get the UUID. 
       var uuid = data.msg; 
       //window.location = NEXT_URL + uuid; 
       window.location = NEXT_URL; 
      } 
     }, 
    }); 
} 


function collectFormData() { 
    // Go through all the form fields and collect their names/values. 
    var fd = new FormData(); 

    $("#upload-form :input").each(function() { 
     var $this = $(this); 
     var name = $this.attr("name"); 
     var type = $this.attr("type") || ""; 
     var value = $this.val(); 

     // No name = no care. 
     if (name === undefined) { 
      return; 
     } 

     // Skip the file upload box for now. 
     if (type === "file") { 
      return; 
     } 

     // Checkboxes? Only add their value if they're checked. 
     if (type === "checkbox" || type === "radio") { 
      if (!$this.is(":checked")) { 
       return; 
      } 
     } 

     fd.append(name, value); 
    }); 

    return fd; 
} 


function handleFiles(files) { 
    // Add them to the pending files list. 
    for (var i = 0, ie = files.length; i < ie; i++) { 
     PENDING_FILES.push(files[i]); 
    } 
} 


function initDropbox() { 
    var $dropbox = $("#dropbox"); 

    // On drag enter... 
    $dropbox.on("dragenter", function(e) { 
     e.stopPropagation(); 
     e.preventDefault(); 
     $(this).addClass("active"); 
    }); 

    // On drag over... 
    $dropbox.on("dragover", function(e) { 
     e.stopPropagation(); 
     e.preventDefault(); 
    }); 

    // On drop... 
    $dropbox.on("drop", function(e) { 
     e.preventDefault(); 
     $(this).removeClass("active"); 

     // Get the files. 
     var files = e.originalEvent.dataTransfer.files; 
     handleFiles(files); 

     // Update the display to acknowledge the number of pending files. 
     $dropbox.text(PENDING_FILES.length + " files ready for upload!"); 
    }); 

    // If the files are dropped outside of the drop zone, the browser will 
    // redirect to show the files in the window. To avoid that we can prevent 
    // the 'drop' event on the document. 
    function stopDefault(e) { 
     e.stopPropagation(); 
     e.preventDefault(); 
    } 
    $(document).on("dragenter", stopDefault); 
    $(document).on("dragover", stopDefault); 
    $(document).on("drop", stopDefault); 
} 

我试图功能从以下链接整合以下JavaScriptFlask Multiple Upload

无法要了解为什么它仍然会打/demo

之后仍然会去

有人可以帮助我,这背景发生了什么?

+0

url_for需要一个函数名。你可以尝试使用url_for('main')重定向吗? –

+1

什么是'main'?它是你的应用还是蓝图? – dirn

+0

URL在网页浏览器中是否更改?并正确显示为页面重新加载 –

回答

2

总之,我的猜测是你错误地期待对XHR请求的响应来改变浏览器的地址。

这里是什么,我认为正在发生的更详细的解释

  1. 用户点击上传按钮
  2. doUpload() JavaScript函数被调用
  3. doUpload()作出了XHR(AJAX)请求UPLOAD_URL(POST /upload
  4. upload() Python函数被调用,成功上传后生成一个“302 Found”重定向响应E要/演示
  5. 浏览器接收该响应,并遵循提供的URL,在这种情况下,进到/演示(注意,这并不改变地址,它在后台发生作为XHR请求的一部分)
  6. demo() Python函数呈现一些HTML,其被返回为“200 OK”响应
  7. 步骤3中的XHR呼叫接收该HTML从步骤5,并检查该响应是否指示成功
  8. success功能被触发并试图解析HTML为JSON JSON.parse(data),应该失败

我已就您的浏览器,JavaScript库,HTML模板和用户交互的一些假设,但我认为这是从您提供的代码,最可能的解释。

建议是第一次尝试用这样的替换return redirect(url_for("main.demo"))

if is_ajax: 
    return ajax_response(True, upload_key) 
else: 
    return redirect(url_for("main.demo")) 

在这种情况下,上传成功window.location = NEXT_URL后会得到你的doUpload()内执行,这将在您的浏览器更改地址。

+0

谢谢你的详细解释。 – analyticalpicasso