简介
Fetch API 提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应。它还提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。 MDN地址
内容
Promise fetch(input[, init]);
返回值:一个 Promise,resolve 时回传 Response 对象。 input 定义要获取的资源 init 可选 一个配置项对象,包括所有对请求的设置 参数见Fetch()
基础实现
fetch ( url, {
body: JSON . stringify ( data) ,
cache: 'no-cache' ,
credentials: 'same-origin' ,
headers: {
'user-agent' : 'Mozilla/4.0 MDN Example' ,
'content-type' : 'application/json'
} ,
method: 'POST' ,
mode: 'cors' ,
redirect: 'follow' ,
referrer: 'no-referrer' ,
} )
. then ( response => response. json ( ) )
发送带凭据的请求
fetch ( 'https://example.com' , {
credentials: 'include'
} )
上传JSON数据
var url = 'https://example.com/profile' ;
var data = { username: 'example' } ;
fetch ( url, {
method: 'POST' ,
body: JSON . stringify ( data) ,
headers: new Headers ( {
'Content-Type' : 'application/json'
} )
} ) . then ( res => res. json ( ) )
. catch ( error => console. error ( 'Error:' , error) )
. then ( response => console. log ( 'Success:' , response) ) ;
上传文件
可以通过 HTML 元素,FormData() 和 fetch() 上传文件。
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: 'PUT' ,
body: formData
} )
. then ( response => response. json ( ) )
. catch ( error => console. error ( 'Error:' , error) )
. then ( response => console. log ( 'Success:' , response) ) ;
上传多个文件
可以通过HTML 元素,FormData() 和 fetch() 上传文件。
var formData = new FormData ( ) ;
var photos = document. querySelector ( "input[type='file'][multiple]" ) ;
formData. append ( 'title' , 'My Vegas Vacation' ) ;
for ( let i = 0 ; i < photos. files. length; i++ ) {
formData. append ( 'photo' , photos. files[ i] ) ;
}
fetch ( 'https://example.com/posts' , {
method: 'POST' ,
body: formData
} )
. then ( response => response. json ( ) )
. then ( response => console. log ( 'Success:' , JSON . stringify ( response) ) )
. catch ( error => console. error ( 'Error:' , error) ) ;
检测请求是否成功
想要精确的判断 fetch() 是否成功,需要包含 promise resolved 的情况,此时再判断 Response.ok 是不是为 true。类似以下代码:
fetch ( 'flowers.jpg' ) . then ( function ( response ) {
if ( response. ok) {
return response. blob ( ) ;
}
throw new Error ( 'Network response was not ok.' ) ;
} ) . then ( function ( myBlob ) {
var objectURL = URL . createObjectURL ( myBlob) ;
myImage. src = objectURL;
} ) . catch ( function ( error ) {
console. log ( 'There has been a problem with your fetch operation: ' , error. message) ;
} ) ;
自定义请求对象
除了传给 fetch() 一个资源的地址,你还可以通过使用 Request() 构造函数来创建一个 request 对象,然后再作为参数传给 fetch()
var myHeaders = new Headers ( ) ;
var myInit = { method: 'GET' ,
headers: myHeaders,
mode: 'cors' ,
cache: 'default' } ;
var myRequest = new Request ( 'flowers.jpg' , myInit) ;
fetch ( myRequest) . then ( function ( response ) {
return response. blob ( ) ;
} ) . then ( function ( myBlob ) {
var objectURL = URL . createObjectURL ( myBlob) ;
myImage. src = objectURL;
} ) ;
Headers对象
var myHeaders = new Headers(init);
init 可选 通过一个包含任意 HTTP headers 的对象来预设你的 Headers
var content = "Hello World" ;
var myHeaders = new Headers ( ) ;
myHeaders. append ( "Content-Type" , "text/plain" ) ;
myHeaders. append ( "Content-Length" , content. length. toString ( ) ) ;
myHeaders. append ( "X-Custom-Header" , "ProcessThisImmediately" ) ;
myHeaders = new Headers ( {
"Content-Type" : "text/plain" ,
"Content-Length" : content. length. toString ( ) ,
"X-Custom-Header" : "ProcessThisImmediately" ,
} ) ;
console. log ( myHeaders. has ( "Content-Type" ) ) ;
console. log ( myHeaders. has ( "Set-Cookie" ) ) ;
myHeaders. set ( "Content-Type" , "text/html" ) ;
myHeaders. append ( "X-Custom-Header" , "AnotherValue" ) ;
console. log ( myHeaders. get ( "Content-Length" ) ) ;
console. log ( myHeaders. getAll ( "X-Custom-Header" ) ) ;
myHeaders. delete ( "X-Custom-Header" ) ;
console. log ( myHeaders. getAll ( "X-Custom-Header" ) ) ;
Guard属性
Headers 对象有一个特殊的 guard 属性。这个属性没有暴露给 Web,但是它影响到哪些内容可以在 Headers 对象中被操作。 none:默认的 request:从 request 中获得的 headers(Request.headers)只读 request-no-cors:从不同域(Request.mode no-cors)的 request 中获得的 headers 只读 response:从 response 中获得的 headers(Response.headers)只读 immutable:在 ServiceWorkers 中最常用的,所有的 headers 都只读。
Response对象
Response 实例是在 fetch() 处理完 promise 之后返回的。
会用到的最常见的 response 属性有:
* Response.status — 整数(默认值为200)为response的状态码。
* Response.statusText — 字符串(默认值为"OK"),该值与 HTTP 状态码消息对应。
* Response.ok — 如上所示,该属性是来检查response的状态是否在 200 - 299(包括200 和 299)这个范围内。该属性返回一个布尔值 (en-US)。
方法
Response.blob()
Response mixin的 blob()方法使用一个 Response 流,并将其读取完成。它返回一个使用Blob解决的promise。
response. blob ( ) . then ( function ( myBlob ) {
} ) ;
var myImage = document. querySelector ( 'img' ) ;
var myRequest = new Request ( 'flowers.jpg' ) ;
fetch ( myRequest)
. then ( function ( response ) {
return response. blob ( ) ;
} )
. then ( function ( myBlob ) {
var objectURL = URL . createObjectURL ( myBlob) ;
myImage. src = objectURL;
} ) ;
Response.json()
Response mixin 的 json() 方法接收一个 Response 流,并将其读取完成。它返回一个 Promise,Promise 的解析 resolve 结果是将文本体解析为 JSON。
response. json ( ) . then ( data => {
} ) ;
Response.text()
Response mixin 的 text() 方法提供了一个可供读取的“返回流”(Response stream),并将它读取完。它返回一个包含 USVString 对象(也就是文本)的 Promise 对象,返回结果的编码永远是 UTF-8。
response. text ( ) . then ( function ( text ) {
} ) ;
Response.formData()
Response 对象中的formData() 方法将 Response 对象中的所承载的数据流读取并封装成为一个对象,该方法将返回一个 Promise 对象,该对象将产生一个FormData 对象。 该方法主要与 service workers 有关.
response. formData ( )
. then ( function ( formdata ) {
} ) ;
Body
类型:
ArrayBuffer ArrayBufferView (Uint8Array等) Blob/File string URLSearchParams FormData
特性检测
if ( self. fetch) {
} else {
}
注意
成功的 fetch() 检查不仅要包括 promise 被 resolve,还要包括 Response.ok 属性为 true。HTTP 404 状态并不被认为是网络错误。 从Firefox 43开始,如果fetch()接收到含有用户名和密码的URL(例如http://user:password@example.com),它将会抛出一个TypeError 。 fetch() 可以接受跨域 cookies;你也可以使用 fetch() 建立起跨域会话。 fetch 不会发送 cookies。除非你使用了credentials 的初始化选项。(自 2017 年 8 月 25 日以后,默认的 credentials 政策变更为 same-origin。Firefox 也在 61.0b13 版本中进行了修改)