如何在 java 配置 spring 中使用 ajax 从表单提交文件?

How to submit file from form using ajax in java config spring?

你好我正在尝试将图像文件上传到 server.I 在上传之前使用 jCrop 裁剪图像并使用 canvas 获取裁剪后的图像 coordinates.I 已包含控制器和 jsp 文件。但是我无法使用 ajax 发送表单数据。

AppController.java

@RequestMapping(value = "/upload", method = RequestMethod.POST)
public String handleFormUpload(@RequestParam("file") MultipartFile file, ModelMap model) throws IOException{
if (!file.isEmpty()) {
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
     String name = auth.getName(); //get logged in username
     BufferedImage src = ImageIO.read(new ByteArrayInputStream(file.getBytes()));
     File destination = new File("/home/me/Desktop/"+name+".png");
     model.addAttribute("username", name);
     // something like C:/Users/tom/Documents/nameBasedOnSomeId.png
     ImageIO.write(src, "png", destination);
     //Save the id you have used to create the file name in the DB. You can retrieve the image in future with the ID.
    }else {
     System.out.println("file is empty");
    }
return "prefs";
}

prefs.jsp

<script type="text/javascript">
$(function(){
    $('.majorpoints').click(function(){
        $(this).find('.hiders').slideToggle();
    });
     $("#imgInp").change(function(){
         var c = $('.cropArea').Jcrop({

             onSelect: updateCoords,

                   bgOpacity:   .4,
                   setSelect:   [ 100, 100, 50, 50 ],
                   aspectRatio: 16 / 9
           });

         function readURL(input) {

                if (input.files && input.files[0]) {
                    var reader = new FileReader();

                    reader.onload = function (e) {
                        $('#blah').attr('src', e.target.result);
                    }

                    reader.readAsDataURL(input.files[0]);
                }
            }
            readURL(this);
        }); 

     $('#btnCrop').click(function () {
            var x1 = $('#x').val();
            var y1 = $('#y').val();
            var width = $('#w').val();
            var height = $('#h').val();
            var canvas = $("#canvas")[0];
            alert(x1+""+y1+""+""+width+""+height);
            var context = canvas.getContext('2d');
            var img = new Image();
            img.onload = function () {
                canvas.height = height;
                canvas.width = width;
                context.drawImage(img, x1, y1, width, height, 0, 0, width, height);
                $("#imgInp").val(canvas.toDataURL("image/jpeg")); 
            };

            var data = new FormData();
            data.append('file', dataURItoBlob(canvas.toDataURL("image/jpeg")));
            $.ajax({
                url: 'upload',
                data: data,
                contentType: false,
                processData: false,
                type: 'POST',
                success: function(data){
                    alert(data);
                }
            }); 

            img.src = $('#blah').attr('src');

        });
});
 function dataURItoBlob(dataURI) {
    // convert base64/URLEncoded data component to raw binary data held in a string
    var byteString;
    if (dataURI.split(',')[0].indexOf('base64') >= 0)
        byteString = atob(dataURI.split(',')[1]);
    else
        byteString = unescape(dataURI.split(',')[1]);

    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

    // write the bytes of the string to a typed array
    var ia = new Uint8Array(byteString.length);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }

    return new Blob([ia], {type:mimeString});
}
function updateCoords(c)
  {
    console.log(c);
    $('#x').val(c.x);
    $('#y').val(c.y);
    $('#w').val(c.w);
    $('#h').val(c.h);
    $('#btnCrop').show();
  };
 </script>


<div id="myModal" class="modal fade" role="dialog">
      <div class="modal-dialog">

        <!-- Modal content-->
        <div class="modal-content">
          <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal">&times;</button>
            <h4 class="modal-title">Modal Header</h4>
          </div>
          <div class="modal-body">
            <form method="POST" action="upload" enctype="multipart/form-data">
                Please select a file to upload : 
                <input type="file" name="file" class="file" id="imgInp" />
                <div class="cropArea">
                    <img id="blah" src="#" alt="your image" />
                </div>
                <input type="hidden" id="x" name="x" />
                <input type="hidden" id="y" name="y" />
                <input type="hidden" id="w" name="w" />
                <input type="hidden" id="h" name="h" />
                <canvas id="canvas" height="5" width="5"></canvas>

            </form>
             <input type="button" id="btnCrop" value="Crop" style="display: none" />
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          </div>
        </div>

      </div>
</div>

您缺少此参数

enctype: 'multipart/form-data'

$.ajax({
        url: 'upload',
        data: data,
        contentType: false,
        processData: false,
        enctype: 'multipart/form-data',
        type: 'POST',
        success: function(data){
                   alert(data);
                }
       });

你应该有这个

var data = new FormData();
data.append('file', jQuery('#imgInp')[0].files[0]);

而不是

jQuery.each(jQuery('#imgInp')[0].files, function(i,file) {
            data.append('file-'+i, file);
        });

稍后编辑 2: 在你的函数 dataURItoBlob(dataURI) 中添加这样的回调:

function dataURItoBlob(dataURI, callback) {
   ...
 callback();
}

然后在

$('#btnCrop').click(function () { ...

data.append('file', dataURItoBlob(canvas.toDataURL("image/jpeg", function(){
            $.ajax({
                url: 'upload',
                data: data,
                contentType: false,
                processData: false,
                type: 'POST',
                success: function(data){
                    alert(data);
                }
            }); 
  })));

这样,您就可以确保在执行 dataURItoBlob 后进行 ajax 调用。