简体   繁体   中英

Upload file + Form Data + Spring MVC + JQuery

I'll try to make this question as simple as I can. I want to upload a file with additional form data via an AJAX submission using JQuery (but also for it to be compatible with ie 7 or ie 8, and asynchronous too)

Without the submit being an AJAX submission via JQuery, the process works fine. Namely I did the following:

  1. declared CommonsMultipartResolver
  2. In controller wrote this handler method

@RequestMapping(value="/processfileupload", method = RequestMethod.POST) public @ResponseBody String handleFileUpload(UploadForm data, BindingResult result) throws Exception {

  ....

}

Where UploadForm is a Spring MVC form object which I bound to the form. Also, I bound the formObject in Spring's form tag like so: enctype="multipart/form-data" .. etc..

Like I said, works perfectly if it is NOT done via an Ajax call via JQuery. Once I tried to make it an Ajax call, the file is always null.

Here is the Ajax call via JQuery

function submitFileUploadViaAjax() {

   $.ajax({

        url: "processfileupload",
        data: $("#file_upload_form").serialize(),
        type: "POST", 
        processData: false,
        contentType: false,

        success: function(data) {
                $(response).html(data);
        },

        error: function (xhr, ajaxOptions, thrownError) {
                if (xhr.readyState == 0 || xhr.status == 0) {
                    // not really an error
                    return;
                } else {
                    alert("XHR Status = "+xhr.status);
                    alert("Thrown Error = "+thrownError);
                    alert("AjaxOptions = "+ajaxOptions)
                }
          }

    });

}

I suspect the problem may be: data: $("#file_upload_form").serialize(),

I have read some suggested solutions for those with similar problems to use a formData object but have read that this won't be compatible with IE 7 or IE 8, is this true?

I head also read the JQuery file upload plug-in would work ( https://github.com/blueimp/jQuery-File-Upload/wiki/How-to-submit-additional-form-data ) but I'm not sure if I'd be able to wire this into spring with spring's great way of binding form data to a form object and then just injecting it into a controller.

Does anyone have their thoughts on the best way to upload a file (relatively small) + have some form data, and be able to process this with a single endpoint in a spring mvc controller? And the solution so that it is compatible with most browsers, but especially will work with ie 7 or ie 8 (it's a requirement it work in those browsers.)

Thanks a bunch!

  • Rocco

File uploading using AJAX is possible: try this

Client Side : HTML

<input type="file" name="file" id="fileLoader" /> 
<input type="button" id="fileSubmit" value="Upload"/>

Client Side : JS

var files = [];
$(document)
        .on(
                "change",
                "#fileLoader",
                function(event) {
                 files=event.target.files;
                })

$(document)
        .on(
                "click",
                "#fileSubmit",
                function() {
                processUpload();
                })

function processUpload()
          {
              var oMyForm = new FormData();
              oMyForm.append("file", files[0]);
             $
                .ajax({dataType : 'json',
                    url : "the url",
                    data : oMyForm,
                    type : "POST",
                    enctype: 'multipart/form-data',
                    processData: false, 
                    contentType:false,
                    success : function(result) {
                        //...;
                    },
                    error : function(result){
                        //...;
                    }
                });
          }

Server Side : JAVA

@RequestMapping(method = RequestMethod.POST, value = "the url")
    @ResponseBody
    public void uploadFile(@RequestParam("file") MultipartFile multipartFile) {
            //...
    }

this worked like a charm for me:

$('#formId').submit(function(evt) {

            evt.preventDefault();

            var formData = new FormData(this);

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

To upload file, use formdata:

function collectFormData(fields) {
    var formData = new FormData();

    for (var i = 0; i < fields.length; i++) {
        var $item = $(fields[i]);

        if ($item.attr('type') =="file"){
            var file = $('input[type=file]')[0].files[0];
            formData.append( $item.attr('name') , file);

        } else {
            formData.append( $item.attr('name') , $item.val());
        }
    }
    return formData;
}

and send:

    var fields = form.find('input, textarea, select');
    var formData = collectFormData(fields);


    $.ajax({
        url: form.attr('action'),
        type: 'POST',
        scriptCharset: "utf-8",
        data: formData,
        async: false,
        cache: false,
        contentType: false,
        processData: false,
        timeout: 600000,
        success: function (response) {
            if (response.status == "SUCCESS"){
                console.log("SUCCESS...");
                $( document ).trigger( "SUCCESS", [ response ] );
            } else if (response.status == "FAIL"){
                console.log("FAIL...");
                clearErrors(form);

                ...
            }
        }
    })

File uploading using AJAX is not possible. AJAX doesn't actually post forms to the server, it sends selected data to the server in the form of a POST or GET request. As javascript is not capable of grabbing the file from the users machine and sending it to the server, it's just not possible with AJAX. You have to resort to regular old form submit.

Follow this link: http://viralpatel.net/blogs/ajax-style-file-uploading-using-hidden-iframe/ for an example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM