《猛戳-查看个人博客地图-总有你意想不到的惊喜》
本文内容:fetch相关javascript
位于 WorkerOrGlobalScope 这一个 mixin 中的 fetch() 方法用于发起获取资源的请求。它返回一个 promise,这个 promise 会在请求响应后被 resolve,并传回 Response 对象。java
Window 和 WorkerGlobalScope 都实现了 WorkerOrGlobalScope。 ——这意味着基本在任何场景下只要你想获取资源,均可以使用 位于 WorkerOrGlobalScope 中的 fetch() 方法。web
Fetch API 提供了一个获取资源的接口(包括跨域请求),Fetch 是对 HTTP 接口的抽象,包括 Request,Response,Headers,Body。得益于 JavaScript 实现的这些抽象好的 HTTP 模块,其余接口可以很方便的使用这些功能。ajax
Fetch 提供了对 Request 和 Response (以及其余与网络请求有关的)对象的通用定义。它同时还为有关联性的概念,例如CORS和HTTP原生头信息,提供一种新的定义,取代它们原来那种分离的定义。json
当接收到一个表明错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即便该 HTTP 响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (可是会将 resolve 的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。跨域
默认状况下,fetch 不会从服务端发送或接收任何 cookies, 若是站点依赖于用户 session,则会致使未经认证的请求(要发送 cookies,必须设置 credentials 选项)。自从2017年8月25往后,默认的credentials政策变动为same-originFirefox也在61.0b13中改变默认值promise
if(window.fetch) { // run my fetch request here } else { // do something with XMLHttpRequest? }
//input 必填 //[, init] 选填 Promise<Response> fetch(input[, init]);
input 定义要获取的资源,能够是两种形式,以下简单请求的两种形式:url字符串 / Request对象cookie
可选的配置项对象,包括全部对请求的设置。可选的参数有:
method, headers, body, mode, credentials, cache, redirect, referer, referrerPolicy, integerity网络
//第一种形式 let url = 'http://www.wanshaobo.com/1.jpg';//必传 let options = { body: JSON.stringify(data), headers: new Headers({ 'Content-Type': 'application/json',//发送数据方式为json //'Content-Type': 'application/x-www-form-urlencoded',//发送数据方式为表单提交 }), method: 'POST', cache: "default",//default, reload, no-cache credentials: 'same-origin',//omit 不携带 same-origin 同源请求携带 include 不管跨域仍是同源请求都会携带 mode: 'cors'//cors, no-cors, same-origin, navigate };//可选 fetch(url, options).then(function(Response){ //fetch方法建立的Promise对象 返回resolved状态的回调函数 //Response对象详解见下表 },function(error){ //fetch方法建立的Promise对象 返回rejected状态的回调函数 }) //第二种形式 let Request = new Request(url, {method: 'POST', body: '{"foo":"bar"}'}); fetch(Request).then(function(Response){ //fetch方法建立的Promise对象 返回resolved状态的回调函数 //Response对象详解见下表 },function(error){ //fetch方法建立的Promise对象 返回rejected状态的回调函数 })
key | value | type |
---|---|---|
Response.headers | 包含此Response所关联的Headers 对象 | 只读 |
Response.ok | 包含了一个布尔值来标示该 Response 成功(状态码的范围在200-299) | 只读 |
Response.redirected | 表示该Response是否来自一个重定向,若是是的话,它的URL列表将会有多个entry | 只读 |
Response.status | 包含Response的状态码 | 只读 |
Response.statusText | 包含了与该Response状态码一致的状态信息 (例如, OK对应 200) | 只读 |
Response.type | 包含Response的类型 (例如, basic, cors) | 只读 |
Response.url | 包含Response的URL | 只读 |
Response.useFinalURL | 包含了一个布尔值来标示这是不是该Response的最终URL | - |
Response.headers | 包含此Response所关联的Headers 对象 | 只读 |
Response.headers | 包含此Response所关联的Headers 对象 | 只读 |
key | value | type |
---|---|---|
Response.json() | 读取 Response对象而且将它设置为已读(由于Responses对象被设置为了 stream 的方式,因此它们只能被读取一次) ,并返回一个被解析为JSON格式的promise对象。 | |
Response.text() | 读取 Response对象而且将它设置为已读(由于Responses对象被设置为了 stream 的方式,因此它们只能被读取一次) ,并返回一个被解析为USVString格式的promise对象。 |
//形式一 var myImage = document.querySelector('img'); var myRequest = new Request('flowers.jpg'); fetch(myRequest).then(function(response) { return response.blob(); }).then(function(response) { var objectURL = URL.createObjectURL(response); myImage.src = objectURL; }); //形式二 var myImage = document.querySelector('img'); var myHeaders = new Headers(); myHeaders.append('Content-Type', 'image/jpeg'); var init = { method: 'GET', headers: myHeaders, mode: 'cors', cache: 'default' }; var myRequest = new Request('flowers.jpg'); fetch(myRequest,init).then(function(response) { ... }); //形式三 var myRequest = new Request('flowers.jpg',myInit); var init = { method: 'GET', headers: { 'Content-Type': 'image/jpeg' }, mode: 'cors', cache: 'default' }; var myRequest = new Request('flowers.jpg', init); fetch(myRequest).then(function(response) { ... });
没有对fetch进行Promise包装,login方法的then回调是Response.json()返回的Promise实例
优势:代码简洁
缺点:不能在request方法体中作全局的res.code状态码统一处理,只能在login方法的then回调中作每个请求的单独处理session
//实际的方法调用 let requestData = {} login(requestData).then(res => { console.log('/abc 接口的返回值',res);// JSON from `response.json()` call }).catch(e => { console.log(e); }) //业务的方法 function login(obj) {//登陆 return request('/abc',obj) } //fetch的包装 function request(url,data) { return fetch(baseURL + url, { body: JSON.stringify(data), headers: new Headers({'Content-Type': 'application/json'}), method: 'POST', cache: "default", credentials: 'include',//'same-origin' 'include' }).then(Response => Response.json(),err => {}).catch((e)=>{}) }
对fetch进行Promise包装,在request方法体中作全局的res.code状态码统一处理,login方法的then回调是包装的Promise的返回值。
//实际的方法调用 let requestData = {} login(requestData).then(res => { //Promise对象resolved console.log('/abc 接口的返回值',res.data); },err => { //Promise对象rejecetd console.log(err) }).catch(e => { //catch方法处理 Promise 内部发生的错误,捕获两种错误: //一、then方法指定的两个回调函数,若是运行中抛出错误,会被catch方法捕获; //二、rejected状态也会被catch方法捕获 //catch方法返回的仍是一个 Promise 对象 console.log(e); }) //业务的方法 function login(obj) {//登陆 return request('/abc',obj) } //fetch的包装 import {message} from "antd"; import { createBrowserHistory } from 'history'; const history = createBrowserHistory(); function request(url,data) { return new Promise((resolve,reject)=>{ fetch(baseURL + url, { body: JSON.stringify(data), headers: new Headers({'Content-Type': 'application/json'}), method: 'POST', cache: "default", credentials: 'same-origin' }).then((Response)=>{ //fetch请求返回resolved状态的回调函数 let data = Response.json()//res是一个json文件,使用 json() 读取并解析数据,返回一个被解析为JSON格式的promise对象 data.then((res,rej)=>{ if(res.code == 100){ resolve(res) }else if(res.code == 11115){ //用户登陆失效,token失效,跳转到登陆页面 history.replace('/login') }else{ message.destroy() message.error(res.message); } }) },err => { //fetch请求返回rejected状态的回调函数 //fetch请求 网络故障时或请求被阻止时,标记为 reject reject(err) }).catch((e)=>{ reject(e) }) }) }
body使用FromData对象,主要用于序列化表单以及建立与表单格式相同的数据
经过HTML元素,FormData() 和fetch()上传文件。
var formData = new FormData(); var fileField = document.querySelector("input[type='file']"); formData.append('username', 'abc123'); formData.append('avatar', fileField.files[0]); function request(url,data) { return new Promise((resolve,reject)=>{ fetch(url, { body: formData, method: 'PUT', }).then((Response)=>{ let data = Response.json() data.then((res,rej)=>{ }) }) }) }
能够经过HTML元素,FormData() 和fetch()上传文件。
var formData = new FormData(); var photos = document.querySelector("input[type='file'][multiple]"); formData.append('title', 'My Vegas Vacation'); formData.append('photos', photos.files); function request(url,data) { return new Promise((resolve,reject)=>{ fetch(url, { body: formData, method: 'PUT', }).then((Response)=>{ let data = Response.json() data.then((res,rej)=>{ }) }) }) }
感谢阅读,欢迎评论^-^
打赏我吧^-^