Is it possible to post image file using the jQuery's ajax post method. Would it work if I just put the file data in the POST request's 'data' parameter?
I am using django framework. This is my first attempt:
$('#edit_user_image').change(function(){
var client = new XMLHttpRequest();
var file = document.getElementById("edit_user_image");
var csrftoken = document.getElementsByName('csrfmiddlewaretoken')[0].value
/* Create a FormData instance */
var formData = new FormData();
formData.append("upload", file.files[0]);
client.open("post", "/upload-image/", true);
client.setRequestHeader("X-CSRFToken", csrftoken);
client.setRequestHeader("Content-Type", "multipart/form-data; charset=UTF-8; boundary=frontier");
client.send(formData); /* Send to server */
});
The problem with this is that I don't get the'request.FILES' object on the serer side in my 'views.py'.
I also tried doing it with ajax post but it doesn't work either.
$('#edit_user_image').change(function(){
var data = {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
content:document.getElementById("edit_user_image").files[0],}
$.post("/upload-image/", data, function(){
});
});
Edit from one of the answers:
$('#edit_user_image').change(function(){
var formData = new FormData($("#edit_user_image")[0]);
$.ajax({
type: "POST",
url: "/upload-image/",
xhr: function() { // custom xhr
// If you want to handling upload progress, modify below codes.
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){ // check if upload property exists
myXhr.upload.addEventListener('progress', yourProgressHandlingFunction, false); // for handling the progress of the upload
}
return myXhr;
},
data: formData,
// Options to tell JQuery not to process data or worry about content-type
cache: false,
contentType: false,
processData: false,
beforeSend: function(xhr) {
// If you want to make it possible cancel upload, register cancel button handler.
$("#yourCancelButton").click(xhr.abort);
},
success: function( data ) {
// Something to do after upload success.
alert('File has been successfully uploaded.');
location.reload();
},
error : function(xhr, textStatus) {
// Something to do after upload failed.
alert('Failed to upload files. Please contact your system administrator. - ' + xhr.responseText);
}
});
});
This is my final working solution:
$('#edit_user_image').change(function(){
var csrftoken = document.getElementsByName('csrfmiddlewaretoken')[0].value
var formData = new FormData($("#edit_user_image")[0]);
var formData = new FormData();
formData.append("file", $('#edit_user_image')[0].files[0]);
formData.append("csrfmiddlewaretoken", csrftoken);
$.ajax({
type: "POST",
url: "/upload-image/",
data: formData,
contentType: false,
processData: false,
});
});
You can if you use FormData, otherwise you have to use Flash or iframes or Plugins (these ones use flash or iframes), FormData comes with HTML5 so it won't work in IE <= 9, a great guy created a replica of FormData for old browsers, to use it you only have to put formdata.js in the head tag. So in my opinion you have to use FormData.
We say you have a form like this:
<form method="POST" name="form" id="form" enctype="multipart/form-data">
<input type="file" id="img"/>
<input type="submit"/>
</form>
you have to get the img chosen by the user so your javascript have to look like this:
$(document).ready(function(){
$('form').on('submit', function(e){
e.preventDefault();
var data = new FormData($('form').get(0));
$.ajax({
url: :"/URL",
method: "POST",
data: data,
success: function(data){},
error: function(data){},
processData: false,
contentType: false,
});
});
});
and now you are going to be able to retrieve the img chosen by the user in django with:
request.FILES
Yes. You can post your image file using jQuery's ajax.
Try below code snippet.
// Your image file input should be in "yourFormID" form.
var formData = new FormData($("#yourFormID")[0]);
$.ajax({
type: "POST",
url: "your_form_request_url",
xhr: function() { // custom xhr
// If you want to handling upload progress, modify below codes.
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){ // check if upload property exists
myXhr.upload.addEventListener('progress', yourProgressHandlingFunction, false); // for handling the progress of the upload
}
return myXhr;
},
data: formData,
// Options to tell JQuery not to process data or worry about content-type
cache: false,
contentType: false,
processData: false,
beforeSend: function(xhr) {
// If you want to make it possible cancel upload, register cancel button handler.
$("#yourCancelButton").click(xhr.abort);
},
success: function( data ) {
// Something to do after upload success.
alert('File has been successfully uploaded.');
location.reload();
},
error : function(xhr, textStatus) {
// Something to do after upload failed.
alert('Failed to upload files. Please contact your system administrator. - ' + xhr.responseText);
}
});
My suggestion is add "return false after the ajax block.
Related
I have an ajax request that is sending a file along with some other info. Everything except the file is the correct value, and the file is always null. I can't figure out why.
Here is the input I have included in the form:
<input type="file" id="file" runat="server"/>
On button click, it calls this function:
function ButtonClick() {
var file = document.getElementById('file').files[0]; // correctly gets the file
var formData = new FormData();
formData.append('key1', 'val1');
formData.append('key2', 'val2');
formData.append('file', file, file.name);
$.ajax({
cache: false,
data: formData,
dataType: 'json',
processData: false,
contentType: false,
success: function (data, textStatus, jqXHR) { closeWindow(); },
timeout: 30000,
type: 'POST',
url: '<%= ResolveClientUrl("~/api/Example/ExampleUrl") %>'
});
}
When I receive the request server-side, I get the following values:
var key1= HttpContext.Current.Request.Form["key1"]); // returns "val1"
var key2= HttpContext.Current.Request.Form["key2"]); // returns "val2"
var file= HttpContext.Current.Request.Form["file"]); // returns "null"
And when I take a look at HttpContext.Current.Request.Form, "file" is not in the request at all.
The file should be accessible via
HttpContext.Current.Request.Files["file"]
I'm trying to do a Ajax's loops requests for send files to an API but i don't not what I send at Ajax's data. When I do only file in upload I use the own formdata object and works very well. I tried use loop and each row send an individual file but it's doesn't works too:
Multiple files:
var form_data = new FormData();
for(i=0;i<3;i++){ // 3 length just for tests
form_data.append('file', $('#myfile').prop('files')[i]);
}
for (var value of form_data.values()) {
$.ajax({
url: 'URI',
data: value,
processData: false,
contentType: false,
type: 'POST',
success: function (data) {
alert("Success!")
},
error: function(e){
alert("Error")
}
});
}
This question already has answers here:
Sending multipart/formdata with jQuery.ajax
(13 answers)
Closed 6 years ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
The XMLHttpRequest Level 2 standard (still a working draft) defines the FormData interface. This interface enables appending File objects to XHR-requests (Ajax-requests).
Btw, this is a new feature - in the past, the "hidden-iframe-trick" was used (read about that in my other question).
This is how it works (example):
var xhr = new XMLHttpRequest(),
fd = new FormData();
fd.append( 'file', input.files[0] );
xhr.open( 'POST', 'http://example.com/script.php', true );
xhr.onreadystatechange = handler;
xhr.send( fd );
where input is a <input type="file"> field, and handler is the success-handler for the Ajax-request.
This works beautifully in all browsers (again, except IE).
Now, I would like to make this functionality work with jQuery. I tried this:
var fd = new FormData();
fd.append( 'file', input.files[0] );
$.post( 'http://example.com/script.php', fd, handler );
Unfortunately, that won't work (an "Illegal invocation" error is thrown - screenshot is here). I assume jQuery expects a simple key-value object representing form-field-names / values, and the FormData instance that I'm passing in is apparently incompatible.
Now, since it is possible to pass a FormData instance into xhr.send(), I hope that it is also possible to make it work with jQuery.
Update:
I've created a "feature ticket" over at jQuery's Bug Tracker. It's here: http://bugs.jquery.com/ticket/9995
I was suggested to use an "Ajax prefilter"...
Update:
First, let me give a demo demonstrating what behavior I would like to achieve.
HTML:
<form>
<input type="file" id="file" name="file">
<input type="submit">
</form>
JavaScript:
$( 'form' ).submit(function ( e ) {
var data, xhr;
data = new FormData();
data.append( 'file', $( '#file' )[0].files[0] );
xhr = new XMLHttpRequest();
xhr.open( 'POST', 'http://hacheck.tel.fer.hr/xml.pl', true );
xhr.onreadystatechange = function ( response ) {};
xhr.send( data );
e.preventDefault();
});
The above code results in this HTTP-request:
This is what I need - I want that "multipart/form-data" content-type!
The proposed solution would be like so:
$( 'form' ).submit(function ( e ) {
var data;
data = new FormData();
data.append( 'file', $( '#file' )[0].files[0] );
$.ajax({
url: 'http://hacheck.tel.fer.hr/xml.pl',
data: data,
processData: false,
type: 'POST',
success: function ( data ) {
alert( data );
}
});
e.preventDefault();
});
However, this results in:
As you can see, the content type is wrong...
I believe you could do it like this :
var fd = new FormData();
fd.append( 'file', input.files[0] );
$.ajax({
url: 'http://example.com/script.php',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
alert(data);
}
});
Notes:
Setting processData to false lets you prevent jQuery from automatically transforming the data into a query string. See the docs for more info.
Setting the contentType to false is imperative, since otherwise jQuery will set it incorrectly.
You can send the FormData object in ajax request using the following code,
$("form#formElement").submit(function(){
var formData = new FormData($(this)[0]);
});
This is very similar to the accepted answer but an actual answer to the question topic. This will submit the form elements automatically in the FormData and you don't need to manually append the data to FormData variable.
The ajax method looks like this,
$("form#formElement").submit(function(){
var formData = new FormData($(this)[0]);
//append some non-form data also
formData.append('other_data',$("#someInputData").val());
$.ajax({
type: "POST",
url: postDataUrl,
data: formData,
processData: false,
contentType: false,
dataType: "json",
success: function(data, textStatus, jqXHR) {
//process data
},
error: function(data, textStatus, jqXHR) {
//process error msg
},
});
You can also manually pass the form element inside the FormData object as a parameter like this
var formElem = $("#formId");
var formdata = new FormData(formElem[0]);
Hope it helps. ;)
There are a few yet to be mentioned techniques available for you. Start with setting the contentType property in your ajax params.
Building on pradeek's example:
$('form').submit(function (e) {
var data;
data = new FormData();
data.append('file', $('#file')[0].files[0]);
$.ajax({
url: 'http://hacheck.tel.fer.hr/xml.pl',
data: data,
processData: false,
type: 'POST',
// This will override the content type header,
// regardless of whether content is actually sent.
// Defaults to 'application/x-www-form-urlencoded'
contentType: 'multipart/form-data',
//Before 1.5.1 you had to do this:
beforeSend: function (x) {
if (x && x.overrideMimeType) {
x.overrideMimeType("multipart/form-data");
}
},
// Now you should be able to do this:
mimeType: 'multipart/form-data', //Property added in 1.5.1
success: function (data) {
alert(data);
}
});
e.preventDefault();
});
In some cases when forcing jQuery ajax to do non-expected things, the beforeSend event is a great place to do it. For a while people were using beforeSend to override the mimeType before that was added into jQuery in 1.5.1. You should be able to modify just about anything on the jqXHR object in the before send event.
I do it like this and it's work for me, I hope this will help :)
<div id="data">
<form>
<input type="file" name="userfile" id="userfile" size="20" />
<br /><br />
<input type="button" id="upload" value="upload" />
</form>
</div>
<script>
$(document).ready(function(){
$('#upload').click(function(){
console.log('upload button clicked!')
var fd = new FormData();
fd.append( 'userfile', $('#userfile')[0].files[0]);
$.ajax({
url: 'upload/do_upload',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
console.log('upload success!')
$('#data').empty();
$('#data').append(data);
}
});
});
});
</script>
JavaScript:
function submitForm() {
var data1 = new FormData($('input[name^="file"]'));
$.each($('input[name^="file"]')[0].files, function(i, file) {
data1.append(i, file);
});
$.ajax({
url: "<?php echo base_url() ?>employee/dashboard2/test2",
type: "POST",
data: data1,
enctype: 'multipart/form-data',
processData: false, // tell jQuery not to process the data
contentType: false // tell jQuery not to set contentType
}).done(function(data) {
console.log("PHP Output:");
console.log(data);
});
return false;
}
PHP:
public function upload_file() {
foreach($_FILES as $key) {
$name = time().$key['name'];
$path = 'upload/'.$name;
#move_uploaded_file($key['tmp_name'], $path);
}
}
You can use the $.ajax beforeSend event to manipulate the header.
…
beforeSend: function(xhr) {
xhr.setRequestHeader('Content-Type', 'multipart/form-data');
}
…
See this link for additional information: http://msdn.microsoft.com/en-us/library/ms536752(v=vs.85).aspx
If you want to submit files using ajax use "jquery.form.js"
This submits all form elements easily.
Samples
http://jquery.malsup.com/form/#ajaxSubmit
rough view :
<form id='AddPhotoForm' method='post' action='../photo/admin_save_photo.php' enctype='multipart/form-data'>
<script type="text/javascript">
function showResponseAfterAddPhoto(responseText, statusText)
{
information= responseText;
callAjaxtolist();
$("#AddPhotoForm").resetForm();
$("#photo_msg").html('<div class="album_msg">Photo uploaded Successfully...</div>');
};
$(document).ready(function(){
$('.add_new_photo_div').live('click',function(){
var options = {success:showResponseAfterAddPhoto};
$("#AddPhotoForm").ajaxSubmit(options);
});
});
</script>
Instead of - fd.append( 'userfile', $('#userfile')[0].files[0]);
Use - fd.append( 'file', $('#userfile')[0].files[0]);
When I push a green button on http://jazzkredit.ru/ after submission form, I get message "ajaxUrl is not defined" instead of image that should pop up and email that I should receive on email.
Can anybody help me to solve this issue? I have tried to search for an answer on Google and in Stackoverflow but it didn't help.
var formData = new FormData($('form#loanappform')[0]);
$.ajax({
url: ajaxUrl, //Server script to process data
type: 'POST',
xhr: function() { // Custom XMLHttpRequest
var myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){ // Check if upload property exists
myXhr.upload.addEventListener('progress',progressHandlingFunction, false); // For handling the progress of the upload
}
return myXhr;
},
//Ajax events
success: completeHandler,
// Form data
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false
});
You need to define ajaxUrl first or just use the direct name of the server-side file to which you are posting:
Method A: var ajaxUrl = "process-ajax.php"
Method B: url: "process-ajax.php"
This question already has answers here:
Sending multipart/formdata with jQuery.ajax
(13 answers)
Closed 6 years ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
The XMLHttpRequest Level 2 standard (still a working draft) defines the FormData interface. This interface enables appending File objects to XHR-requests (Ajax-requests).
Btw, this is a new feature - in the past, the "hidden-iframe-trick" was used (read about that in my other question).
This is how it works (example):
var xhr = new XMLHttpRequest(),
fd = new FormData();
fd.append( 'file', input.files[0] );
xhr.open( 'POST', 'http://example.com/script.php', true );
xhr.onreadystatechange = handler;
xhr.send( fd );
where input is a <input type="file"> field, and handler is the success-handler for the Ajax-request.
This works beautifully in all browsers (again, except IE).
Now, I would like to make this functionality work with jQuery. I tried this:
var fd = new FormData();
fd.append( 'file', input.files[0] );
$.post( 'http://example.com/script.php', fd, handler );
Unfortunately, that won't work (an "Illegal invocation" error is thrown - screenshot is here). I assume jQuery expects a simple key-value object representing form-field-names / values, and the FormData instance that I'm passing in is apparently incompatible.
Now, since it is possible to pass a FormData instance into xhr.send(), I hope that it is also possible to make it work with jQuery.
Update:
I've created a "feature ticket" over at jQuery's Bug Tracker. It's here: http://bugs.jquery.com/ticket/9995
I was suggested to use an "Ajax prefilter"...
Update:
First, let me give a demo demonstrating what behavior I would like to achieve.
HTML:
<form>
<input type="file" id="file" name="file">
<input type="submit">
</form>
JavaScript:
$( 'form' ).submit(function ( e ) {
var data, xhr;
data = new FormData();
data.append( 'file', $( '#file' )[0].files[0] );
xhr = new XMLHttpRequest();
xhr.open( 'POST', 'http://hacheck.tel.fer.hr/xml.pl', true );
xhr.onreadystatechange = function ( response ) {};
xhr.send( data );
e.preventDefault();
});
The above code results in this HTTP-request:
This is what I need - I want that "multipart/form-data" content-type!
The proposed solution would be like so:
$( 'form' ).submit(function ( e ) {
var data;
data = new FormData();
data.append( 'file', $( '#file' )[0].files[0] );
$.ajax({
url: 'http://hacheck.tel.fer.hr/xml.pl',
data: data,
processData: false,
type: 'POST',
success: function ( data ) {
alert( data );
}
});
e.preventDefault();
});
However, this results in:
As you can see, the content type is wrong...
I believe you could do it like this :
var fd = new FormData();
fd.append( 'file', input.files[0] );
$.ajax({
url: 'http://example.com/script.php',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
alert(data);
}
});
Notes:
Setting processData to false lets you prevent jQuery from automatically transforming the data into a query string. See the docs for more info.
Setting the contentType to false is imperative, since otherwise jQuery will set it incorrectly.
You can send the FormData object in ajax request using the following code,
$("form#formElement").submit(function(){
var formData = new FormData($(this)[0]);
});
This is very similar to the accepted answer but an actual answer to the question topic. This will submit the form elements automatically in the FormData and you don't need to manually append the data to FormData variable.
The ajax method looks like this,
$("form#formElement").submit(function(){
var formData = new FormData($(this)[0]);
//append some non-form data also
formData.append('other_data',$("#someInputData").val());
$.ajax({
type: "POST",
url: postDataUrl,
data: formData,
processData: false,
contentType: false,
dataType: "json",
success: function(data, textStatus, jqXHR) {
//process data
},
error: function(data, textStatus, jqXHR) {
//process error msg
},
});
You can also manually pass the form element inside the FormData object as a parameter like this
var formElem = $("#formId");
var formdata = new FormData(formElem[0]);
Hope it helps. ;)
There are a few yet to be mentioned techniques available for you. Start with setting the contentType property in your ajax params.
Building on pradeek's example:
$('form').submit(function (e) {
var data;
data = new FormData();
data.append('file', $('#file')[0].files[0]);
$.ajax({
url: 'http://hacheck.tel.fer.hr/xml.pl',
data: data,
processData: false,
type: 'POST',
// This will override the content type header,
// regardless of whether content is actually sent.
// Defaults to 'application/x-www-form-urlencoded'
contentType: 'multipart/form-data',
//Before 1.5.1 you had to do this:
beforeSend: function (x) {
if (x && x.overrideMimeType) {
x.overrideMimeType("multipart/form-data");
}
},
// Now you should be able to do this:
mimeType: 'multipart/form-data', //Property added in 1.5.1
success: function (data) {
alert(data);
}
});
e.preventDefault();
});
In some cases when forcing jQuery ajax to do non-expected things, the beforeSend event is a great place to do it. For a while people were using beforeSend to override the mimeType before that was added into jQuery in 1.5.1. You should be able to modify just about anything on the jqXHR object in the before send event.
I do it like this and it's work for me, I hope this will help :)
<div id="data">
<form>
<input type="file" name="userfile" id="userfile" size="20" />
<br /><br />
<input type="button" id="upload" value="upload" />
</form>
</div>
<script>
$(document).ready(function(){
$('#upload').click(function(){
console.log('upload button clicked!')
var fd = new FormData();
fd.append( 'userfile', $('#userfile')[0].files[0]);
$.ajax({
url: 'upload/do_upload',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
console.log('upload success!')
$('#data').empty();
$('#data').append(data);
}
});
});
});
</script>
JavaScript:
function submitForm() {
var data1 = new FormData($('input[name^="file"]'));
$.each($('input[name^="file"]')[0].files, function(i, file) {
data1.append(i, file);
});
$.ajax({
url: "<?php echo base_url() ?>employee/dashboard2/test2",
type: "POST",
data: data1,
enctype: 'multipart/form-data',
processData: false, // tell jQuery not to process the data
contentType: false // tell jQuery not to set contentType
}).done(function(data) {
console.log("PHP Output:");
console.log(data);
});
return false;
}
PHP:
public function upload_file() {
foreach($_FILES as $key) {
$name = time().$key['name'];
$path = 'upload/'.$name;
#move_uploaded_file($key['tmp_name'], $path);
}
}
You can use the $.ajax beforeSend event to manipulate the header.
…
beforeSend: function(xhr) {
xhr.setRequestHeader('Content-Type', 'multipart/form-data');
}
…
See this link for additional information: http://msdn.microsoft.com/en-us/library/ms536752(v=vs.85).aspx
If you want to submit files using ajax use "jquery.form.js"
This submits all form elements easily.
Samples
http://jquery.malsup.com/form/#ajaxSubmit
rough view :
<form id='AddPhotoForm' method='post' action='../photo/admin_save_photo.php' enctype='multipart/form-data'>
<script type="text/javascript">
function showResponseAfterAddPhoto(responseText, statusText)
{
information= responseText;
callAjaxtolist();
$("#AddPhotoForm").resetForm();
$("#photo_msg").html('<div class="album_msg">Photo uploaded Successfully...</div>');
};
$(document).ready(function(){
$('.add_new_photo_div').live('click',function(){
var options = {success:showResponseAfterAddPhoto};
$("#AddPhotoForm").ajaxSubmit(options);
});
});
</script>
Instead of - fd.append( 'userfile', $('#userfile')[0].files[0]);
Use - fd.append( 'file', $('#userfile')[0].files[0]);