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

Posted

技术标签:

【中文标题】如何从 VueJs 提交“multipart/form-data”【英文标题】:how to submit "multipart/form-data" from VueJs 【发布时间】:2017-09-20 08:30:40 【问题描述】:

我在前端使用 VueJs / axios,在 nodejs 中使用 multer 来进行简单的文件上传。

到目前为止,所有尝试均未成功。 虽然这可以使用 ng-upload 和其他类似插件以 1/2 角的 100 种方式实现。但是 VueJs 似乎缺少这个基本功能。 根据我的研究,axios 不支持“multipart/form-data”。参考https://github.com/mzabriskie/axios/issues/789。

multer 和其他 nodejs 库似乎可以从 angular 1/2 无缝地使用“multipart/form-data”。但是,VueJs 无法使用相同的功能。

除了支持“multipart/form-data”又名——WebKitFormBoundary 的 axios 之外,还有其他选择吗??

非常感谢

【问题讨论】:

好吧,Axios 并不是唯一的库……Vue 资源 github.com/pagekit/vue-resource/issues/267 怎么样?是的,我知道他们说..但对我来说它仍然很好 引用的链接说 node.js 不支持 FormData 对象。也不应该真的,FormData 是一个浏览器构造。 Axios 支持从浏览器提交 FormData 就好了。 codepen.io/Kradek/pen/aWmomM?editors=1010 @BertEvans - 非常感谢您的意见。是的,它适用于 axios 和使用 formData() 的新 XMLHttpRequest()。 FormData 是一个很好的解决方案吗? caniuse.com/#search=FormData @Sumanta 取决于您的用例,但通常没问题。 【参考方案1】:

我在 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() 浏览器支持的一个有趣点在这里caniuseFormData

也适用于像我一样尝试通过 axios 使其与 content-type = "multipart/form-data" 一起使用的人。它行不通。

【讨论】:

【参考方案2】:

您可以为此使用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 => ...)
    

这应该可以解决问题,您实际上并不需要 3rd 方插件。

【讨论】:

确实,这样更方便,恕我直言【参考方案3】:

我还遇到了一个问题,我必须将一些其他信息与图像一起发送。我想分享我所做的。 我正在尝试上传图片、种类、名称和 eventID。

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)

【讨论】:

以上是关于如何从 VueJs 提交“multipart/form-data”的主要内容,如果未能解决你的问题,请参考以下文章

图片上传 - 在点击提交之前在网页上显示图片

如何在提交侦听器上传递表单数据,以便 axios 可以发布表单数据?

vueJS 3.x:在 HTML 表单提交后从页面导航

Vuejs - 如何在单个表单中仅提交可见元素(使用 Vuelidate)

如何在 VueJS 的 SetTimeOut 中提交存储

如何在 vuejs2 中执行“用户停止输入后提交表单”