V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
PeiXyJ
V2EX  ›  问与答

使用 axios 上传图片错误,但是使用 postman 可以上传

  •  1
     
  •   PeiXyJ · 2019-09-25 16:49:09 +08:00 · 3256 次点击
    这是一个创建于 1887 天前的主题,其中的信息可能已经有所发展或是发生改变。

    使用 axios 上传图片错误,但是使用 postman 可以上传

    $imgAdd (pos, $file) {
          let vm = this.$refs.md
          // 第一步.将图片上传到服务器.
          let formdata = new FormData()
          formdata.append('image',$file)
          axios({
            headers: { 'Content-Type': 'multipart/form-data' },
            url: 'http://localhost:8080/api/v1/image/upload/markdown',
            method: 'post',
            data: { 'image': formdata }
          }).then((url) => {
            // 第二步.将返回的 url 替换到文本原位置![...](0) -> ![...](url)
            /**
               * $vm 指为 mavonEditor 实例,可以通过如下两种方式获取
               * 1. 通过引入对象获取: `import {mavonEditor} from ...` 等方式引入后,`$vm`为`mavonEditor`
               * 2. 通过$refs 获取: html 声明 ref : `<mavon-editor ref=md ></mavon-editor>,`$vm`为 `this.$refs.md`
               */
            // vm.$img2Url(pos, url)
          }).catch(function (error) {
            alert(error)
          })
        }
    

    java 中的错误信息为

    org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
    
    

    java 代码

    @RequestMapping(value = "markdown")
        @ResponseBody
        public JsonData upload(@RequestParam("image") MultipartFile file) {
            if (file.isEmpty() || file.getSize() > FileSize.MB_COEFFICIENT) {
                return JsonData.buildError("文件不存在或者文件太大");
            }
    
            String name = file.getOriginalFilename();
            String suffixName = null;
            if (name != null) {
                suffixName = name.substring(name.indexOf(".") - 1);
            } else {
                suffixName = ".jpg";
            }
            String fileName = UUID.randomUUID() + suffixName;
    
            File markdownImageFile = new File(MARKDOWN_IMAGE_FILE +fileName);
            try {
                file.transferTo(markdownImageFile);
                return JsonData.buildSuccess(fileName);
            } catch (IOException e) {
                e.printStackTrace();
                return JsonData.buildError(e.getMessage());
            }
        }
    

    麻烦大佬们帮忙看看外网测试地址 http://api.ngrok.peixy.top/api/v1/image/upload/markdown

    第 1 条附言  ·  2019-09-25 17:32:21 +08:00
    已经改成
    ```
    data: formdata
    ```
    外网测试的暂时关闭,下班回家
    第 2 条附言  ·  2019-09-25 17:32:47 +08:00
    错误信息应该是 缺少 boundary 值
    14 条回复    2019-09-26 12:36:05 +08:00
    nigelvon
        1
    nigelvon  
       2019-09-25 16:53:40 +08:00
    { 'image': $file } 换成 formdata
    PeiXyJ
        2
    PeiXyJ  
    OP
       2019-09-25 16:55:11 +08:00
    @nigelvon 不行,我测试过...
    jtwor
        3
    jtwor  
       2019-09-25 17:19:52 +08:00
    用 formdata 不行就先判断好是 传有问题 还是接收有问题
    baiyi
        4
    baiyi  
       2019-09-25 17:22:10 +08:00
    axios data 是不是多了一个 image,直接 data: formdata 呢
    optional
        5
    optional  
       2019-09-25 17:23:30 +08:00
    @baiyi #4+1
    nigelvon
        6
    nigelvon  
       2019-09-25 17:26:41 +08:00
    不行估计是$file 有问题,建议 f12 截图一下 network 里的详细信息
    PeiXyJ
        7
    PeiXyJ  
    OP
       2019-09-25 22:31:28 +08:00 via iPhone
    @jtwor 传有问题控制台里的 content-type 缺值
    PeiXyJ
        8
    PeiXyJ  
    OP
       2019-09-25 22:32:02 +08:00 via iPhone
    @baiyi 这个发现了改过后尝试也不可以
    redbuck
        9
    redbuck  
       2019-09-25 23:17:31 +08:00 via Android
    去掉 headers 里的 content-type
    redbuck
        10
    redbuck  
       2019-09-25 23:23:26 +08:00 via Android
    formdata 其实就是用一个 boundary 分割序列化的字符串,你指定了 content-type 但是没有指定 boundary,导致服务端不知道怎么去分割反序列化你的 formdata,就解析失败了。

    实际上 axios 新版本应该修改了,data 是 formdata 实例时,会直接无视用户指定的 content-type
    PeiXyJ
        11
    PeiXyJ  
    OP
       2019-09-26 09:39:47 +08:00
    ```
    $imgAdd (pos, $file) {
    // 第一步.将图片上传到服务器.
    let formData = new FormData()
    formData.append('file', $file)
    console.log($file)
    console.log(formData)
    let url = 'http://localhost:8080/api/v1/image/upload/markdown'
    axios.post(url, formData).then(function (res) {
    alert(res)
    }).catch(function (error) {
    alert(error)
    })

    // axios({
    // url: 'http://localhost:8080/api/v1/image/upload/markdown',
    // method: 'post',
    // data: formdata,
    // headers: { 'Content-Type': 'multipart/form-data' }
    // }).then((url) => {
    // // 第二步.将返回的 url 替换到文本原位置![...](0) -> ![...](url)
    // // $vm.$img2Url 详情见本页末尾
    // })
    }
    ```
    在这样输出后,我发现
    console.log($file)
    console.log(formData)
    在$file 是有内容的
    在 formdata 中没有$file 的内容
    PeiXyJ
        12
    PeiXyJ  
    OP
       2019-09-26 11:12:10 +08:00
    @redbuck @baiyi @jtwor @nigelvon @optional 嗯,解决了,我用的框架是 d2 admin 它在 main 方法中给我过滤了 axios,导致传输失败.
    redbuck
        13
    redbuck  
       2019-09-26 11:15:35 +08:00   ❤️ 1
    @PeiXyJ formData 直接打印看不到东西的,你的 formdata.get(key)
    PeiXyJ
        14
    PeiXyJ  
    OP
       2019-09-26 12:36:05 +08:00
    @redbuck 嗯我看到了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5842 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 03:39 · PVG 11:39 · LAX 19:39 · JFK 22:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.