2013-01-13 65 views
2

我正在嘗試爲我的Django表單實現AJAX表單提交。Ajax表單提交,未提交的文件

這些文件正在提交沒有AJAX,所以在服務器端的邏輯似乎正在工作。和ajax,其餘的值除了文件被提交。

下面是我實現的代碼,

AJAX表單提交

(function() { 
    // using jQuery 
    function getCookie(name) { 
    var cookieValue = null; 
    if (document.cookie && document.cookie != '') { 
     var cookies = document.cookie.split(';'); 
     for (var i = 0; i < cookies.length; i++) { 
     var cookie = jQuery.trim(cookies[i]); 
     // Does this cookie string begin with the name we want? 
     if (cookie.substring(0, name.length + 1) == (name + '=')) { 
      cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 
      break; 
     } 
     } 
    } 
    return cookieValue; 
    } 
    var csrftoken = getCookie('csrftoken'); 
    function csrfSafeMethod(method) { 
    // these HTTP methods do not require CSRF protection 
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
    } 
    $.ajaxSetup({ 
    crossDomain: false, // obviates need for sameOrigin test 
    beforeSend: function(xhr, settings) { 
    if (!csrfSafeMethod(settings.type)) { 
     xhr.setRequestHeader("X-CSRFToken", csrftoken); 
    } 
    } 
    }); 
})(); 

jQuery的

$('#save-form').live('submit', function(event) { // catch the form's submit event 
    event.preventDefault(); 
    $.ajax({ // create an AJAX call... 
     data: $(this).serialize(), // get the form data 
     type: $(this).attr('method'), // GET or POST 
     url: '/save/', // the file to call 
     success: function(response) { // on success.. 
      $('#modalsave-form').html(response); // update the DIV 
     } 
    }); 
    return false; 
}); 

HTML表單

<form class="form-horizontal" id="save-form" enctype="multipart/form-data" method="post" action="/save/"> 
    <div class="control-group"> 
     <label class="control-label" for="id_body">Write Something</label> 
     <div class="controls"> 
      <textarea class="typeaheadfun" id="id_body" rows="3" cols="100" name="body" placeholder="Scribble Body" style="width: 455px;"></textarea> 
     </div> 
    </div> 
    <div class="control-group"> 
     <label class="control-label" for="id_media">Add a File</label> 
     <div class="controls"> 
      <input type="file" name="media" id="id_media"/> 
     </div> 
    </div> 
    <hr> 
    <input class="btn btn-primary pull-right" type="submit" value="Post!" /> 
    <br> 
    {% csrf_token %} 
</form> 
+2

我已經問了這個問題。看看這裏http://stackoverflow.com/questions/14026889/django-file-upload-not-working-with-ajax 嘗試使用jquery表單插件 –

+0

@RaunakAgarwal感謝您的評論:) jQuery表單插件太棒了! – Jonathan

回答

2

當您提交HTML表單它通常發送fo使用GETPOST數據HTML標頭將rm的數據發送到服務器。但是,無論您需要將二進制數據還是附加文件有效發送到服務器,作爲其中一部分的HTML spec都有不同的發送此類數據的方法。 enctype<form>標籤的屬性指定了瀏覽器應該使用哪種方法將數據發送到服務器。發送文件,multipart/form-data是應用廣泛的編碼方法。

當您嘗試發送形式沒有Ajax,瀏覽器使用multipart/form-data編碼但文件的數據發送到服務器,當你使用AJAX提交表單你執行以下操作:

data: $(this).serialize() 

這一步不編碼數據與服務器期望數據的方式相同,因此您的ajax不起作用。

爲了使它工作,而不是手動提交表單的數據,你應該使用ajax提交整個表單。手動操作很棘手,加上有插件可以做到這一點。一個這樣的插件是jQuery Form Plugin。它允許使用ajax提交整個表單。下面是js代碼應該給你如何將它與您的設置集成了一個想法:

$('#save-form').live('submit', function(event) { 
    event.preventDefault(); 

    $(this).ajaxSubmit({ 
     url: '/save/', // the file to call 
     success: function(response) { 
      $('#modalsave-form').html(response); 
     } 
    }); 

    return false; 
}); 
+0

非常感謝! :) 這太棒了!並且很容易使用! 那麼你會建議我讓所有的表單都使用這個插件嗎?即使他們不需要提交文件?這種方法與我使用的方法有什麼特別的優勢? – Jonathan

+0

我通常使用這種方法,因爲它更簡單,更容易維護,並且允許更復雜的表單(例如使用'file'標籤等) – miki725

1

另一種選擇是使用FORMDATA接口,免除了插件

https://developer.mozilla.org/en-US/docs/Web/API/FormData

需要

示例代碼:(適應,以滿足您的需求)

`

$('#fupload').click(function(){ 

var xhr = new XMLHttpRequest(); 

var token = $('input[name="csrfmiddlewaretoken"]').prop('value'); 
    $.ajaxSetup({ 
     headers: { "X-CSRFToken": token } 
    });  

var formData = new FormData($('form')[0]); 
formData.append('file',xhr.file); 

    $.ajax({ 
     url: '/myurl/', //server script to process data 
     type: 'POST', 
     xhr: function() { // custom xhr 
      myXhr = xhr; 
      //if(xhr.upload){ // check if upload property exists 
      // xhr.upload.addEventListener('progress',progressHandlingFunction, false); 
       // for handling the progress of the upload 
      //} 
      return xhr; 
     }, 
     // Form data 
     data: formData, 
     //Ajax events 
     success: function(server_response){ 
      $('#path').val("Success"); 
     }, 
     error: function(jqXHR, textStatus, errorThrown){ 
      $('#path').val(errorThrown); 
     }, 
     //Options to tell JQuery not to process data or worry about content-type 
     cache: false, 
     contentType: false, 
     processData: false 
    }); 
}); 

`