toothie
toothie

Reputation: 1029

POST data using AJAX POST

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);
      }
    });  
  });

Upvotes: 2

Views: 2535

Answers (4)

Victor Castillo Torres
Victor Castillo Torres

Reputation: 10811

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

Upvotes: 1

Angry Cat
Angry Cat

Reputation: 251

My suggestion is add "return false after the ajax block.

Upvotes: 0

toothie
toothie

Reputation: 1029

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, 

    });  
  });

Upvotes: 1

Hosang Jeon
Hosang Jeon

Reputation: 1423

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);
    }
});  

Upvotes: 0

Related Questions