我正在尝试为我的Django表单实现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);
}
}
});
})();
$('#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;
});
<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>
答案 0 :(得分:2)
当您提交HTML表单时,它通常会使用GET
或POST
数据HTML标头将表单数据发送到服务器。但是,当您需要有效地将二进制数据或附加文件发送到服务器时,作为其spec的一部分的HTML具有用于发送此类数据的不同方法。 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;
});
答案 1 :(得分: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
});
});
`