资讯专栏INFORMATION COLUMN

antd 和 element上传文件详解与FormData详解

Fundebug / 2075人阅读

摘要:当用户完成选择文件动作时,提交子页面中的。从此我们上传文件就欢欣鼓舞的来找了。因为的核心是对象,异步的实现是通过一个对象,一般简称该对象对。这些回答基于自己理解,如有不妥,希望路过的大神轻喷,指正。

背景

平时工作中经常会遇到需要上传文件的情况,如果你用ant design 或者element ,它们都提供了上传的组件。 我们分别来看一下element 和 antd 手动上传怎么处理:

ant design 手动上传文件

antd官网有手动上传的demo:
在这里简单写一写实现,主要有 在jsx中引入Upload组件,将 fileList 作为props传入,fileList为选择的文件列表,和 上传函数的实现。

// jsx
 
// Upload 为上传组件
//  handleUpload 的实现 使用 fetch 请求
const handleUpload = () {
    const formData = new FormData();
    fileList.forEach((file) => {   // fileList 是要上传的文件数组
      formData.append("files[]", file);
    });
    
    fetch(url: "http:just.a.url.demo", {
      method: "POST",
      headers: {
            credentials: "same-origin"
          // "Content-Type": "multipart/form-data"  // 不要加上这个文件类型说明
      },
      body: formData
            
    })
    .then(response => response.json())
    .catch(error => console.error("Error:", error))
    .then(response => console.log("Success:", response));
}
Element 手动上传文件

element 和antd 不同,通过上传组件拿回的数据,element又封装了一层,所以传数据稍有不同。
以下是简单实现:

// template

    选择文件
    上传文件

//  上传实现

const handleUpload = () {
    const formData = new FormData();
    fileList.forEach((file) => {        
        formData.append("files[]", file.raw);  // 这里与antd 不同的是,文件真正数据为 file.raw 
    });
    
    fetch(url: "http:just.a.url.demo", {
      method: "POST",
      headers: {
            credentials: "same-origin"
          // "Content-Type": "multipart/form-data"  // 不要加上这个文件类型说明
      },
      body: formData
            
    })
    .then(response => response.json())
    .catch(error => console.error("Error:", error))
    .then(response => console.log("Success:", response));
}
想问几个问题:

虽然可以找得demo把文件传输了出去,但是心里有几个问题,如下:

1. 问什么传文件需要用FormData格式呢?传文件和传一般数据有什么不一样?

从传文件的历史来回答传文件问什么需要FormData 格式。

file 形式

在最开始的时候,文件上传的传统形式是使用 表单元素file。参照下面的代码:

  
    
       

它在chrome浏览器中是这个样子:

选择文件之后,点击Upload 按钮,文件开始上传。

iframe形式

使用form元素比较简单,但缺点也比较明显:上传同步、上传完成页面会刷新;
在HTML5出现之前,想要实现文件异步上传,只能通过iframe+form实现;
其原理是:文件上传时在页面中动态创建一个iframe元素和一个form元素,并将form元素的target属性指向动态创建iframe元素。当用户完成选择文件动作时,提交子页面中的 form。这时,iframe跳转,而父页面没有刷新。这使得上传结束后,服务器处理结果返回到动态iframe窗口而没有刷新页面;
具体code,这里不再枚举,感兴趣童鞋可以去 iframe+form 查看。

ajax + FormData 形式

哎呀,终于来到了现代社会,并且见到了咱们的主角 FormData。 ajax 大家肯定都知道了,异步刷新,无需重新加载整个网页的情况下,便能够更新部分网页。
那FormData 是什么呢? FormData是XMLHttpRequest Level 2添加的一个新接口,他可以 构建类似表单的键值对, 也就是说我们可以利用 FormData 来模拟表单控件,然后使用XMLHttpRequest的send()
方法来异步的提交这个"表单"。
看一下简单的使用 FormData传文件的例子


        
    
    

选择文件并上传后,通过浏览器看看网络情况。

答案

啰啰嗦嗦这么多,终于知道了为什么传文件要用FormData了!!开心,简单来说就是,传文件一开始设计使用 form 来传,但是呢,使用form默认的上传方式存在诸多问题,比如同步啦,我想在上传之前处理一下数据啦,这个时候FormData 就站出来了,大喊 我可以构建类似表单的键值对,来模拟表单,发送的数据用我构建的对象就可以上传文件了。从此我们上传文件就欢欣鼓舞的来找FormData了。
好了,另一个小问题,文件和其他数据的不同,文件传输时是二进制数据,所以格式和一般数据不一样。 我们的FormData大侠不仅可以传文件也可以传一般数据哦,当然传输数据有很多种方式,比如get请求的时候跟在url后面。

2. 请求为什么要用fetch呢? 和过气网红Ajax 什么关系?和xhr 有什么关系呢?

认真看过问题1的回答,这个问题就很简单了。fetch api 是一个提供请求资源(包括通过网络)的接口,它和xhr(XMLHttpRequest)类似。
所以请求不是为什么要用fetch,而是fetch 只是一种方法,可以用fetch也可以用xhr(参考问题一中的 ajax + FormData demo),他们逻辑上是‘并列’的。
至于问和AJAX 什么关系,不如说 Ajax 和 xhr什么关系。因为Ajax的核心是XMLHttpRequest对象, Ajax异步的实现是通过new 一个 XMLHttpRequest对象,一般简称该对象对xhr。所以这里 fetch 是Ajax或XMLHttpRequest的一个替代方案。

3. 为什么传文件的时候,"content-type"不能指定 "multipart/form-data" 呢?

当指定为"multipart/form-data"的时候,还需要指定 boundary=something。如果不指定则会自动分配。

ps: 这些回答基于自己理解,如有不妥,希望路过的大神轻喷,指正。

FormData

MDN上这样解释FormData:
The FormData interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest.send() method.It uses the same format a form would use if the encoding type were set to "multipart/form-data".
FormData 接口提供了一种方法,可以方便地构造一组表示表单字段和它们的值的键值对,然后可以使用XMLHtRPROQuest.send()方法轻松发送。如果一个表单设置编码格式为 multipart/form-data, 这个表单将和FormData 使用相同的格式。

从头说起 FormData

XHR

fetch

MDN 这样介绍Fetch,Fetch API 是和XHR类似的用于获取资源(包括通过网络)的一种接口方法,但是 Fetch API提供了更强大更灵活的API。fetch()便是其中一个全局方法。

3.1 XHR(XMLHttpRequest) 和 fetch 什么关系?

Fetch和XHR平行关系,

3.2 fetch 和 FormData

先来看fetch()几种常见的用法:

Uploading JSON data: POST JSON-encoded data.
var url = "https://example.com/profile";
var data = {username: "example"};

fetch(url, {
  method: "POST", // or "PUT"
  body: JSON.stringify(data), // data can be `string` or {object}!
  headers:{
    "Content-Type": "application/json"
  }
}).then(res => res.json())
.catch(error => console.error("Error:", error))
.then(response => console.log("Success:", response));
upload a file
var formData = new FormData();
var fileField = document.querySelector("input[type="file"]");

formData.append("username", "abc123");
formData.append("avatar", fileField.files[0]);

fetch("https://example.com/profile/avatar", {
  method: "POST",
  body: formData
})
.then(response => response.json())
.catch(error => console.error("Error:", error))
.then(response => console.log("Success:", response));

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96386.html

相关文章

  • 图片上传方案详解

    摘要:以往用到图片上传功能都是直接使用现成的插件,今天把其中用到的知识点整理一下。构造函数返回一个新构造的。事件及方法我们主要是用事件及方法,其他见处理事件。继续使用上文的读取图片读取完成是格式的图片我们将上的设为读取的结果即可实现预览功能。 以往用到图片上传功能都是直接使用现成的插件,今天把其中用到的知识点整理一下。 知识点字典 input 标签之 file 类型 FileReader ...

    glumes 评论0 收藏0
  • 图片上传方案详解

    摘要:以往用到图片上传功能都是直接使用现成的插件,今天把其中用到的知识点整理一下。构造函数返回一个新构造的。事件及方法我们主要是用事件及方法,其他见处理事件。继续使用上文的读取图片读取完成是格式的图片我们将上的设为读取的结果即可实现预览功能。 以往用到图片上传功能都是直接使用现成的插件,今天把其中用到的知识点整理一下。 知识点字典 input 标签之 file 类型 FileReader ...

    Karuru 评论0 收藏0
  • 系统学习前端之FormData详解

    摘要:概述类型其实是在级定义的,它是为序列化表以及创建与表单格式相同的数据当然是用于传输提供便利。如果是使用表单初始化,每一个表单字段对应一条数据,它们的属性即为值,它们属性对应值。参考兼容性查询高级程序设计 FormData 1. 概述 FormData类型其实是在XMLHttpRequest 2级定义的,它是为序列化表以及创建与表单格式相同的数据(当然是用于XHR传输)提供便利。 2. ...

    jhhfft 评论0 收藏0
  • XMLHTTPRequest属性、方法、事件大全&详解

    摘要:属性方法事件整理大全。有严格安全限制。值描述将设为空字符串与设置为相同,是默认类型实际上是。默认值为空字符串只有当为时,对象上才有此属性,此时才能调用,否则抛错。以下种情况下值都为空字符串请求未完成请求失败。 XMLHTTPRequest属性、方法、事件整理大全。 xhr 对象的方法 open(method:string, url:string, async?:boolean=tr...

    roadtogeek 评论0 收藏0
  • Vue实现Excel本地下载及上传的方法详解

      在开发中,文件上传下载是常见相关功能,现在就Excel在该功能进行讲述:  咱直接看代码:  <divclass="import-main-content">   <divclass="import-main-button"@click="checkFile">   <divclass="imp...

    3403771864 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<