-2

I have read tons of Q&A about AJAX file upload but none of them works for me. I'm using Chrome 59 and Safari 10.

What is wrong with this AJAX call?

$(function() {
    $('#filesubmit').submit(function(e) {
        e.preventDefault();

        let file = $('#inputfile').prop('files')[0];
        let formData = new FormData();
        formData.append('file', file);

        $.ajax({
            type: 'POST',
            url: 'getArchFromNet/',
            data: formData,
            processData: false,
            contentType: false,
            cache: false,
            success: function(response) {
                alert('ok');
            }
        });
    });
});

Maybe the problem is in my HTML, which is a bit messy, but I don't think so... anyway, here it is:

<form action="POST" id="filesubmit" style="display:none;">
    <p>
        <input id="inputfile" name="inputfile" type="file" onchange="$('#filesubmit').submit();" />
        <input type="submit" name="sendfile" value="sendfile" />
    </p>
</form>
<p id="net_actions">
    <a id="load_net" href="javascript:$('#inputfile').click();"><img src="{% static 'upload.png' %}" alt="upload a network" /></a>
    <a id="save_net" href="saveNet/?job_id=" type="application/octet-stream"><img src="{% static 'download.png' %}" alt="download the network" /></a>
</p>

Specifically, what happens in my HTML is this: when a user clicks on the #load_net anchor, the browser clicks the #inputfile file input; when the user has chosen a file, the browser clicks the #sendfile submit input and this triggers my JS function.

The problem is that an empty payload is being sent, instead of my file. I have also tried to use let file = $('#inputfile').files[0]; and let file = $('#inputfile').get(0).files[0]; but none of them works.

Giorgio
  • 2,137
  • 3
  • 20
  • 40
  • You may use formData instead of a new obj? – Jonas Wilms Jun 28 '17 at 09:03
  • 1
    Yes it is possible, I do that ten times before lunch each day! What is the error? – philipp Jun 28 '17 at 09:05
  • @Jonasw Sorry, I will now edit my post. But actually I get an empty payload even with my `formData` variable. – Giorgio Jun 28 '17 at 09:06
  • 1
    First check the developer console (network tab) to see if the form data is correctly added to the body of the request, than check the server response to see what is wrong. – philipp Jun 28 '17 at 09:07
  • Where is enctype='multipart/form-data' form attribute..? – Nono Jun 28 '17 at 09:14
  • @philipp My payload seems to be "------WebKitFormBoundaryGvzzgFUtH1ZmCBhk Content-Disposition: form-data; name="file"; filename="p2net.txt" Content-Type: text/plain ------WebKitFormBoundaryGvzzgFUtH1ZmCBhk--" – Giorgio Jun 28 '17 at 09:15
  • @NeerajSingh is it necessary? I tried to add it to the form before but it didn't change anything. – Giorgio Jun 28 '17 at 09:17
  • Hi. This may help - https://stackoverflow.com/questions/12966433/convert-form-data-to-json-object – Sagar Jun 28 '17 at 09:34
  • It is important to understand that the body will contain a content type for each file. So your server must be able to parse that right. `new FormData()` will do for sure. – philipp Jun 28 '17 at 09:47

2 Answers2

1

I had the same problem a couple of days ago. I solved the problem by serialize the files and form data, before sending to a servlet.

$.fn.serializefiles = function () {
    var obj = $(this);
    var formData = new FormData();
    $.each($(obj).find("input[type='file']"), function (i, tag) {
        $.each($(tag)[0].files, function (i, file)
        {
            formData.append(tag.name, file);
        });
    });
    var params = $(obj).serializeArray();
    $.each(params, function (i, val) {
        formData.append(val.name, val.value);
    });
    return formData;
};

jQuery.fn.serializeObject = function () {
    var arrayData, objectData;
    arrayData = this.serializeArray();
    objectData = {};

    $.each(arrayData, function () {
        var value;

        if (this.value != null) {
            value = this.value;
        } else {
            value = '';
        }

        if (objectData[this.name] != null) {
            if (!objectData[this.name].push) {
                objectData[this.name] = [objectData[this.name]];
            }
            objectData[this.name].push(value);
        } else {
            objectData[this.name] = value;
        }
    });

    return objectData;
};

Call the method by the following:

var serializedFormData = $("#formData").serializeObject();

My ajax call is the following:

                     $.ajax({
                        method: "POST",
                        url: urlPath,
                        processData: true,
                        dataType: "json",
                        contentType: "application/json; charset=utf-8",
                        data: JSON.stringify(serzializedFormObject)
                    }).done(function (_p) {
                    }).fail(function (xhr, status, error) {
                    });

Maybe an alternative is that you convert the file object to base64 via the html5 canvas reader and send it in a string.

Thomas Z.
  • 566
  • 6
  • 21
0

"Is AJAX file upload really possible?"

Yes! Big YES!!! but for those who knows How to Code or How to Copy.. :D

If you are not familiar with JavaScript or jQuery or your basics are still growing then it might be look IMPOSSIBLE for you.. but believe me when you become more experience & take time to learn techniques You Can Make Your Own Tank .. :D

Your code is absolutely fine, but the culprit is below html code.

<a id="load_net" href="javascript:$('#inputfile').click();">
  <img src="{% static 'upload.png' %}" alt="upload a network" />
</a>

You know what is this code doing...When user clicking on this hyperlink/tag/button the browser immediately attempting to open 'href reference page' which is actually a jQuery code, The file selection popup surely will open, but once user select their file their browser going to be hang (FF) or jQuery error on null or boom boom!!. So simple answer is When Your Code is not actually on real page its opening jQuery script code or placing your href code in Browser's address bar/Url bar "javascript:$('#inputfile').click();" That's the reason your are not able to execute your JavaScript code. So best would be change your html code as below to take a fresh breath faster....:

<a id="load_net" href="javascript:void(0);" onclick="$('#inputfile').click();">
   <img src="{% static 'upload.png' %}" alt="upload a network" />
</a>

Update the code and get 'file' POST input on AjaxPOST.. :) Good luck!

Nono
  • 6,986
  • 4
  • 39
  • 39
  • Sorry if I answer only now. Actually I was able to trigger the POST request even before. The problem is more about submitting the payload, I think. – Giorgio Jun 30 '17 at 10:42