【问题标题】:Send multipart request from ajax to spring controller without form?将多部分请求从ajax发送到没有表单的spring控制器?
【发布时间】:2017-05-03 01:05:30
【问题描述】:

我正在从桌面上传一张图片,并将这张图片转换为 javascript 中的基本代码。之后,我想将此图像基本代码与多部分请求一起发送到 spring 控制器。但我没有使用表单。

HTML

 <input id="inputFileToLoad" type="file"  onchange="encodeImageFileAsURL()">   

JAVA 脚本

 window.photoCakeUrl = '<c:url value="/media/image/upload"/>';
      function encodeImageFileAsURL() {
                var filesSelected = document.getElementById("inputFileToLoad").files;
                if (filesSelected.length > 0) {
                    var fileToLoad = filesSelected[0];
                    var fileReader = new FileReader();
                    fileReader.onload = function (fileLoadedEvent) {
                        var srcData = fileLoadedEvent.target.result; // <--- data: base64
                        var newImage = document.createElement('img');
                        var photoCake = srcData;
                        newImage.src = srcData;
                        document.getElementById("imgTest").innerHTML = newImage.outerHTML;
                        var ajax1 = $.ajax({
                            type: 'POST',
                            url: photoCakeUrl,
                            processData: false, // important
                            contentType: false, // important
                            dataType: 'json',
                            data: {photoCak: photoCake}
                        });

                      });

                    },
                            fileReader.readAsDataURL(fileToLoad);
                }
            }

弹簧控制器:

@RequestMapping(value = "/media/image/upload", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, String> productPictureUploadnew(MultipartHttpServletRequest request, HttpServletResponse response) {
        Map<String, String> resp = new HashMap<>();
        String photoCake = request.getParameter("photoCak");


        System.out.println("photoCake   " + photoCake);

        return resp;
    }

但是当我生成 AJAX 调用时,会出现 500 错误。如果我只是使用

public Map<String, String> productPictureUploadnew(HttpServletRequest
 request, HttpServletResponse response)

然后就可以了。意思是当我使用 MultipartHttpServletRequest 的地方 HttpServletRequest 请求然后它不起作用。

【问题讨论】:

  • 您不是在发送多部分请求,而是在 JSON 对象中发送 base64 编码的文件数据。
  • 是的,但我想通过多部分请求发送此数据..
  • 然后只需提交包含您的inputFileToLoad 的表单。哦,当然要在表单上设置enctype="multipart/form-data"
  • 但是,我不想使用表单..
  • 那你为什么要使用multipart呢?对不起,但我真的不明白你想要达到的目标。显然你有一个工作上传,为什么还要改变它?

标签: javascript java ajax spring multipart


【解决方案1】:

您将其作为 multipart/form-data 发送可能是 HttpServletRequest 无法获取您的数据的原因,请从 ajax 调用中删除 contentType 选项,然后 jquery 将使用默认向导。 '应用程序/x-www-form-urlencoded; charset=UTF-8'

var ajax1 = $.ajax({
                       type: 'POST',
                        url: photoCakeUrl,
                        processData: false, // important
                        dataType: 'json',
                        data: {photoCak: photoCake}
                    });

【讨论】:

    【解决方案2】:

    我得到了解决方案,我们可以在 javascript 中使用 formData,而无需在任何 JSP 中使用 form 来发送 MultipartHttpServletRequest。

     window.photoCakeUrl = '<c:url value="/media/image/upload"/>';
          function encodeImageFileAsURL() {
                    var filesSelected = document.getElementById("inputFileToLoad").files;
                    if (filesSelected.length > 0) {
                        var fileToLoad = filesSelected[0];
                        var fileReader = new FileReader();
                        fileReader.onload = function (fileLoadedEvent) {
                            var srcData = fileLoadedEvent.target.result; // <--- data: base64
                            var newImage = document.createElement('img');
                            var photoCake = srcData;
                            newImage.src = srcData;
                            document.getElementById("imgTest").innerHTML = newImage.outerHTML;
    
                            var formData = new FormData();
                            formData.append("imgFile", document.getElementById("inputFileToLoad").files[0]);
    
                            var ajax1 = $.ajax({
                                type: 'POST',
                                url: photoCakeUrl,
                                dataType: 'json',
                                data: {photoCak: photoCake}
                            });
    
                          });
    
                        },
                                fileReader.readAsDataURL(fileToLoad);
                    }
                }
    

    var formData = new FormData();
    formData.append("imgFile", document.getElementById("inputFileToLoad").files[0]);

    控制器:

     @RequestMapping(value = "/media/image/upload", method = RequestMethod.POST)
            @ResponseBody
            public Map<String, String> productPictureUploadnew(MultipartHttpServletRequest request, HttpServletResponse response) {
                Map<String, String> resp = new HashMap<>();
                System.out.println("fsasasafsafsafsafsa");
                Iterator<String> itr = request.getFileNames();
    
                String photoCake = request.getParameter("photoCak");
                File file;
              ----------
               -------
              ----------              
    
                return resp;
            }
    

    谢谢,希望对大家有帮助。

    【讨论】:

      【解决方案3】:

      这就是我的做法:

      window.photoCakeUrl = '<c:url value="/media/image/upload"/>';
      window.URL = window.URL || window.webkitURL
      
      function encodeImageFileAsURL() {
        var filesSelected = $('#inputFileToLoad')[0].files;
      
        if (filesSelected.length) {
          var fileToLoad = filesSelected[0];
          var img = new Image();
          var formData = new FormData();
      
          formData.append('imgFile', fileToLoad);
      
          img.onload = function() {
            // only append the image once it's loaded so we don't append broken images
            $('#imgTest').html(this);
            URL.revokeObjectURL(this.src); // Release memory
            // Uploading a image when we can ensure it's a image that can be loaded
            fetch(photoCakeUrl, {method: 'POST', body: formData});
          }
      
          img.onerror = function() {
            // You didn't upload a image
          }
      
          img.src = URL.createObjectURL(srcData);
        }
      }
      
      • URL.createObjectURLfaster,它使用的内存少于长 base64 字符串,它的大小也大了约 3 倍,并且使用了 2 倍以上的内存,因为它存储在 utf16 而不是 utf8 中
      • 您可以使用new Image,它是createElement('img') 的更好的分拣器版本
      • 然后我也会使用Fetch 而不是$.ajax 因为jQuery 愚蠢地处理formData(需要将processData 和contentType 设置为false)
      • 然后我还将accept="images/*" 属性添加到文件输入以过滤掉图像

      【讨论】:

        猜你喜欢
        • 2016-05-17
        • 1970-01-01
        • 2016-03-16
        • 2018-01-25
        • 1970-01-01
        • 2019-12-26
        • 2017-03-31
        • 2021-08-09
        • 1970-01-01
        相关资源
        最近更新 更多