如何从VueJs提交“multipart / form-data”

8

我正在前端使用VueJs/axios,后端使用nodejs的multer来实现简单文件上传。但是目前所有尝试都没有成功。

虽然在angular1 /2中可以使用ng-upload等类似插件的100种方法实现此功能,但VueJs似乎缺少这个基本功能。根据我的研究,axios不支持 "multipart/form-data"。请参阅 https://github.com/mzabriskie/axios/issues/789

multer和其他nodejs库似乎可以从angular 1/2无缝地支持 "multipart/form-data",但是从VueJs中同样的功能却不能正常工作。

是否有其他替代方案除了axios之外,可支持 "multipart/form-data",也就是--WebKitFormBoundary?

非常感谢


好吧,Axios并不是唯一的库...那Vue Resource怎么样呢 https://github.com/pagekit/vue-resource/issues/267?是的,我知道他们说了...但对我来说它仍然工作得非常好。 - Belmin Bedak
1
参考链接称node.js不支持FormData对象。实际上,也不应该支持,因为FormData是一个浏览器构造。Axios支持在浏览器中很好地提交FormData。https://codepen.io/Kradek/pen/aWmomM?editors=1010 - Bert
@BertEvans - 非常感谢您的建议。是的,使用axios和new XMLHttpRequest()都可以使用formData()。FormData是一个好的解决方案吗?http://caniuse.com/#search=FormData - Sumanta
@Sumanta 取决于您的使用情况,但通常是可以的。 - Bert
3个回答

13

我在VueJs中发现了两种实现这个的方法,可能还有更多。

选项1:使用Axios。基于Bert Evans上面的答案。

const formData = new FormData();
  formData.append("file", _file);
  formData.append("id", 7878);
  axios.post("/api/uploadFile", formData)
    .then(function (result) {
      console.log(result);
    }, function (error) {
      console.log(error);
    });

选项 2. 使用本机XMLHttpRequest()

 var formData = new FormData();
  formData.append("file", _file);
  formData.append("id", 7878);
  var request = new XMLHttpRequest();
  request.open("POST", "/api/uploadFile");
  request.send(formData);
  request.onreadystatechange = function () {
    if (request.readyState === 4) {
      if (request.status === 200 && request.statusText === 'OK') {
        console.log('successful');
      } else {
        console.log('failed');
      }
    }
  }

值得注意的是,这里有一个关于FormData()浏览器支持的有趣点。

对于那些像我一样尝试使用axios和content-type = "multipart/form-data"的人来说,它不会起作用。


8
你可以使用 FormData 来实现,这非常简单。
让我给你展示一个例子:
// html    
<button ref="uploadBtn" @onChange="upload">Upload Files</button>

// js
methods: {
    upload () {
        let files = this.$refs.uploadBtn.files
        let formData = new FormData()

        // if you want to upload multiple files at once loop 
        // through the array of files
        formData.append('attachment', files[0])
        axios.post(url, formData).then(response => ...)
    }
}

这应该可以解决问题,而且你不需要第三方插件来完成。

实际上,在我看来,这更方便。 - Billal Begueradj

2
我也遇到了一个问题,需要在上传图片时发送其他信息。我想分享一下我做的事情。 我正在尝试上传图片、类型、名称和事件ID。
let logo1 = new FormData
logo1.append('image', this.logo1)
logo1.append('kind', 'logo1')
logo1.append('name', this.$refs.logo1.files[0].name )
logo1.append('eventID',eventID)


axios.post(`/upload`, logo1,
        
  {
    headers:{
      'Authorization' : `${token}`,
      'Content-Type': `multipart/form-data; boundary=${logo1._boundary}` 
 },    

 }).then((res) => {

     console.log(res)


}).catch((error) => {

    console.log(error)

})

注意:postdata参数的格式应为(url,FormData),而不是(url,{data: FormData})。

在标题中添加“boundary”解决了我的问题(经过3-4个小时)。非常感谢你! - Eflyax

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接