2016-03-04 48 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