zoukankan      html  css  js  c++  java
  • 关于ajaxFileUpload上传控件可能出现的问题

    一.问题

      在前端中,使用jquery的上传插件ajaxFileUpload去上传文件。控制台发现后端接口调通并返回信息,但ajaxFileUpload插件却同时进入error和success的回调函数,且不能获取到后端返回的信息。

    二.代码

      先看看前后端代码。

    //前端
    $.ajaxFileUpload
        (
            {
                url: 'xxx', //用于文件上传的服务器端请求地址
                type: 'post',
                validSuffixes: ["xlsx", "xls"],//允许上传的文件类型(小写)
                fileSize: 1024,//单位为MB
                secureuri: false, //一般设置为false
                fileElementId: "importrebatelist", //文件上传空间的id属性
                contentType: false,
                processData: false,
                dataType: 'json', //返回值类型 一般设置为json
                success: function (data, status)  //服务器成功响应处理函数
                {
                    //
                },
                error: function (data, status) {
                    //
                }
            }
        );
    
    //后端
    @ApiOperation(value = "接口", httpMethod = "POST")
    @RequestMapping(value = "/importFileData", method = RequestMethod.POST)
    public Result importFileData(@RequestParam("importrebatelist") MultipartFile file) {
        Result rm = new Result();
        if (file.isEmpty()) {
            rm.setMessage("未接收到文件");
            rm.setSuccess(false);
        } else {
            String importResult = "";
            if (StringUtil.isNotEmpty(importResult)) {
                rm.setSuccess(false);
                rm.setMessage(importResult);
            } else {
                rm.setSuccess(true);
                rm.setMessage("导入成功");
            }
        }
        return rm;
    }

    三.分析  

      执行上传操作时,后端返回正常,而前端的回调函数同时进入error和success。去查看ajaxFileUpload插件代码发现了问题。

     

       原来是涉及到跨域问题,在解释为何会出现跨域前,这里就要解释一下关于ajax上传的原理。

      一般来说,ajax是不能发送文件,上传文件都是使用表单提交的方式,而表单提交,就需要刷新页面,这点就不符合ajax(ajax是无刷新页面来获取和提交信息)。而ajaxFileUpload上传插件使用的原理也很简单,通过创建一个iframe页面,在这个子iframe页面进行表单提交,而后端返回的信息就显示到iframe页面中,这样主页面就不需要刷新,主页面获取iframe页面的信息就能得到返回信息。基于这个原理,ajaxFileUpload就能实现无刷新上传文件。

    四.解决方案

      首先,后端的返回信息一定是要返回String,或者HttpServletResponse设置content-type为text/html。如果后端选择直接返回对象的话,在ajaxFileUpload生成的iframe页面得到的返回信息会带上html标签,如下图。根据ajaxFileUpload源码原有的处理方式,主页面就会获取不到iframe的信息,继而得不到后端返回结果,且由于报错问题,会进入error和success的回调函数。

       iframe去做和主页面不同源的请求时会出现跨域问题,所以需要前后端同时配合,手动将其设置为同源。

    //后端接口返回
    String domain = "location.hostname"; //设置domain,用于跨域
    String setDomain = "<script>document.domain = " + domain + ";</script>";
    return setDomain + JSON.toJSONString(rm);
    
    //前端
    document.domain = location.hostname;
    $.ajaxFileUpload({
        url:'xxx',
        //...
    });

    5.总结

      ajaxFileUpload插件可能出现的两大问题,接口返回格式处理出错(后端需返回字符)以及跨域问题,基本就可以按照上面的方法去解决。

  • 相关阅读:
    C++ 多线程 (4) 互斥量(mutex)与锁(lock)
    C++ 多线程(3)std::thread 详解
    c++ 多线程(2)创建线程对象的方法
    CMake解决c++11的phread库问题:undefined reference to `pthread_create’
    生成对抗网络--Generative Adversarial Networks (GAN)
    语义分割(semantic segmentation)——U-Net
    目标检测SSD: Single Shot MultiBox Detector
    基于内容的图像检索(CBIR) ——以图搜图
    去噪自动编码器
    利用Chrome开发者工具功能进行网页整页截图的方法
  • 原文地址:https://www.cnblogs.com/shadoll/p/14289658.html
Copyright © 2011-2022 走看看