JS25 上传文件
JS中上传文件的两种原生方法
[TOC]
使用form
标签
<form>
标签用于为用户输入创建HTML表单,向服务器传输数据。
表单能够包含<input>
元素,比如文本字段、复选框、单选框、提交按钮等等。表单还可以包含menus
、textarea
、fieldset
、legend
和label
元素。
注意:
form
元素是块级元素,其前后会产生折行。
1 | <form id="myForm" action="http://www.w3school.com.cn/example/html/form_action.asp"> |
在一个表单里面,action
规定当提交表单时向何处发送表单数据。当点击form
表单内,type
为submit
的按钮时,会将表单提交到action
对应的地址,而点击type
为reset
的按钮时,表单会被重置
想要阻止提交或者重置行为,需要使用e.preventDefault()
FormData
对象
兼容性
除了使用<from>
标签之外,还可以使用FormData
对象来实现文件的上传
它是XMLHttpRequest Level 2添加的接口,浏览器兼容性如下:
利用FormData
对象,可以通过添加一些键值对来模拟一系列表单空间,可以用XMLHttpRequest的send
方法来提交表单。
使用FormData
的最大优点是可以异步上传一个二进制文件。
FormData
对象的API
append
delete
get
getAll
has
set
keys
values
forEach
entries
FormData对象的操作方法,全部在原型中,自己本身没任何的属性及方法,都需要同时实例调用
1 | let formData = new FormData() |
最常用的就是append
方法:
1 | formData.append(name, value, filename); |
其中:
name
,是value
中数据对应的表单名称value
,表单的值,可以是字符串,也可以是Blob
对象(包括子类型,比如File
)filename
,当一个Blob
或者File
作为第二个参数的时候,Blob
对象的默认文件名是blob
。File
对象的默认文件名是该文件的名称。这个名称将指定在Content-Disposition
指定
从零创建一个FormData
对象
1 | const formData = new FormData(); |
FormData对象的字段类型可以是Blob
、File
或者string
,如果它的字段类型不是Blob
也不是File
,则会被转换成字符串类型。
借助<input>
上传
上传文件时可以直接使用获取<input>
的files
内容来直接添加到formData
里。
1 | <input type="file" name="file" required /> |
1 | // HTML 文件类型 input,由用户选择 |
借助Blob
对象上传
也可以使用Blob
对象来实现文件的上传。
一个Blob
对象表示一个不可变的二进制对象,它表示的数据不一定是一个JavaScript原生格式。实际上File
接口基于Blob
,继承blob
功能并将其扩展为支持用户系统上的文件
1 | // Blob对象 |
<form>
标签与formData
相结合
想要构造一个包含<Form>
表单数据的FormData
对象,需要在创建FormData
对象时指定表单的元素。
1 | const formData = new FormData(someFormElement); |
还以最上面的表单为例,
1 | const url = 'http://www.w3school.com.cn/example/html/form_action.asp'; |
可以在创建一个包含Form
表单数据的FormData
对象之后和发送请求之前,附加额外的数据到FormData
对象里
跨域问题
注意,通过<form>
的action
发送表单时,是不受跨域的限制的,因为:跨域指的是跨域资源共享。当一个资源从该改资源本身所在服务器的不同的域或不同的端口请求一个资源时,资源会发起一个跨域HTTP请求。
直接使用<form>
的action
发送表单的时候,是直接把请求交给了action
里面的域,本身页面不会去管他的请求结果,后面的步骤交给了action
里面的域。好比:
1 | <from action="baidu.com/form/a"> |
上面这个表单提交后,剩余的操作就交给了action
里面的域baidu.com/form/a
,本页面的逻辑和这个表单没啥关系,由于不关心请求的响应,所以浏览器认为是安全的。
而使用Ajax来控制form
的请求的时候,页面需要知道请求的返回值,这个时候,浏览器发出跨域请求,需要获得授权才可以成功请求,否则是会拒绝的。