fetch知识点汇总
使用XHR发送一个json请求一般是这样:
const xhr = new XMLHttpRequest()
xhr.open('Get', url)
xhr.responseType = 'json' xhr.onload = () => {
console.log(xhr.response)
} xhr.onerror = () => {
console.log('error')
} xhr.send()
使用fetch的实例:
fetch(url).then(response => response.json())
.then(data => console.log(data))
.catch(e => console.log('error', e))
Fetch参数
fetch(input [,init])
input(必须) 定义要获取的资源(请求地址)
init(可选)
参数 | 描述
method 请求使用的方法,如GET、POST
headers http请求头(user-Agent, Cookie)
body 请求的body信息
mode
fetch可以设置不同的模式使得请求有效. 模式可在fetch方法的第二个参数对象中定义.
可定义的模式如下:
- same-origin: 表示同域下可请求成功; 反之, 浏览器将拒绝发送本次fetch, 同时抛出错误 “TypeError: Failed to fetch(…)”.
- cors: 表示同域和带有CORS响应头的跨域下可请求成功. 其他请求将被拒绝.
- cors-with-forced-preflight: 表示在发出请求前, 将执行preflight检查.
- no-cors: 常用于跨域请求不带CORS响应头场景, 此时响应类型为 “opaque”.
除此之外, 还有两种不太常用的mode类型, 分别是 navigate , websocket , 它们是 HTML标准 中特殊的值, 这里不做详细介绍.
credentials
omit(缺省值,默认为该值)、same-origin(同源,便是同域请求才发送cookie)、include(任何请求都带cookie)
cache
- default(表示fetch请求之前将检查下http的缓存)
- no-store(表示fetch请求将完全忽略http缓存的存在,这意味着请求之前将不再检查下http的缓存, 拿到响应后, 它也不会更新http缓存)
- no-cache(如果存在缓存,那么fetch将发送一个条件查询request和一个正常的request, 拿到响应后,它会更新http缓存)
- reload(表示fetch请求之前将忽略http缓存的存在, 但是请求拿到响应后,它将主动更新http缓存)
- force-cache(表示fetch请求不顾一切的依赖缓存, 即使缓存过期了,它依然从缓存中读取. 除非没有任何缓存, 那么它将发送一个正常的request)
- only-if-cached(表示fetch请求不顾一切的依赖缓存, 即使缓存过期了,它依然从缓存中读取. 如果没有缓存, 它将抛出网络错误(该设置只在mode为”same-origin”时有效).
如果fetch请求的header里包含 If-Modified-Since, If-None-Match, If-Unmodified-Since, If-Match, 或者 If-Range 之一, 且cache的值为 default , 那么fetch将自动把 cache的值设置为 "no-store"
Fetch - response type
一个fetch请求的相应类型(response.type)为如下三种之一:
- baisc (同域下,相应类型为basic)
- cors (同样是跨域下, 如果服务器返回了CORS响应头, 那么响应类型将为 “cors”. 此时响应头中除 Cache-Control , Content-Language , Content-Type , Expores , Last-Modified 和 Progma 之外的字段都不可见.)
- opaque ( 跨域下, 服务器没有返回CORS响应头, 响应类型为 “opaque”. 此时我们几乎不能查看任何有价值的信息, 比如不能查看response, status, url等等等等.)
注意: 无论是同域还是跨域, 以上 fetch 请求都到达了服务器.
Fetch 常见坑
1.Fetch 请求默认是不带 cookie 的,需要设置 fetch(url, {credentials: 'include'})
默认情况下, fetch 不会从服务端发送或接收任何 cookies, 如果站点依赖于维护一个用户会话,则导致未经认证的请求(要发送 cookies,必须发送凭据头)
2.服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。
当接收到一个代表错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即使该 HTTP 响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 reolve 的返回值的 ok 属性设置为 false, 想要精确判断fetch()是否成功,需要包含 promise resolved 的情况,此时再判断 Response.ok 是不是为 true。HTTP状态码为200-299是才会设置为true), 仅当网络故障时或请求被阻止时,才会标记为 rejec
使用Fetch封装request方法
http.js
import 'whatwg-fetch'; const netErrorStatu = 1; // 网络错误
const serverErrorStatu = 2; // 服务器错误
const formatErrorStatu = 3; // 数据格式错误
const logicErrorStatu = 4; // 业务逻辑错误 const errorMsg = {
[netErrorStatu]: '网络错误',
[serverErrorStatu]: '服务器错误',
[formatErrorStatu]: '数据格式错误',
[logicErrorStatu]: '业务逻辑错误'
}; class CustomFetchError {
constructor(errno, data) {
this.errno = errno;
this.msg = errorMsg[errno];
this.data = data;
}
} export function buildQuery(data) {
const toString = Object.prototype.toString; const res = Object.entries(data).reduce((pre, [key, value]) => {
let newValue; if (Array.isArray(value) || toString.call(value) === '[object Object]') {
newValue = JSON.stringify(value);
} else {
newValue = (value === null || value === undefined) ? '' : value;
} pre.push(`${key}=${encodeURIComponent(newValue)}`); return pre;
}, []); return res.join('&');
} export async function request(input, opt) {
// 设置请求默认带cookie
const init = Object.assign({
credentials: 'include'
}, opt); let res;
// 仅当网络故障时或请求被阻止时,才会标记为 rejec
try {
res = await fetch(input, init);
} catch (e) {
throw new CustomFetchError(netErrorStatu, e);
}
// 仅HTTP状态码为200-299是才会设置为true
if (!res.ok) {
throw new CustomFetchError(serverErrorStatu, res);
} let data;
// fetch()请求返回的response是Stream对象,调用response.json时由于异步读取流对象所以返回的是一个Promise对象
try {
data = await res.json();
} catch (e) {
throw new CustomFetchError(formatErrorStatu, e);
}
// 根据和后台的约定设置的错误处理
if (!data || data.errno !== 0) {
throw new CustomFetchError(logicErrorStatu, data);
} return data.data;
} export function get(url, params = {}, opt = {}) {
const init = Object.assign({
method: 'GET'
}, opt); // ajax cache
Object.assign(params, {
timestamp: new Date().getTime()
}); const paramsStr = buildQuery(params); const urlWithQuery = url + (paramsStr ? `?${paramsStr}` : ''); return request(urlWithQuery, init);
} export function post(url, params = {}, opt = {}) {
const headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}; const init = Object.assign({
method: 'POST',
body: buildQuery(params),
headers
}, opt); return request(url, init);
} export default {
request,
get,
post
};
requset.js
import { notification } from 'antd';
import Loading from 'components/Loading';
import { LOGIN_URL } from 'constants/basic';
import * as http from './http'; const loading = Loading.newInstance(); async function request(method, url, params, opt = {}, httpOpt) {
/**
* needLoading 是否添加loading图片
* checkAccount 验证未登陆是否跳登陆页面
* showErrorMsg 是都显示通用错误提示
*/
const {
needLoading = true,
checkAccount = true,
showErrorMsg = true
} = opt; if (needLoading) {
loading.add();
} let res; try {
res = await http[method](url, params, httpOpt);
} catch (e) {
if (checkAccount && e.errno === 4 && e.data.errno === 10000) {
location.href = LOGIN_URL;
} if (showErrorMsg) {
notification.error({
message: '提示信息',
description: e.errno === 4 ? e.data.msg : e.msg
});
} throw e;
} finally {
if (needLoading) {
loading.remove();
}
} return res;
} export function get(...arg) {
return request('get', ...arg);
} export function post(...arg) {
return request('post', ...arg);
}
github的代码地址: https://github.com/haozhaohang/library
fetch知识点汇总的更多相关文章
- nginx几个知识点汇总
WHY? 为什么用Nginx而不用LVS? 7点理由足以说明一切:1 .高并发连接: 官方测试能够支撑 5 万并发连接,在实际生产环境中跑到 2 - 3 万并发连接数.?2 .内存消耗少: 在 3 万 ...
- python全栈开发 * 10知识点汇总 * 180612
10 函数进阶 知识点汇总 一.动态参数 形参的第三种1.动态接收位置传参 表达:*args (在参数位置编写 * 表⽰接收任意内容) (1)动态位置参数def eat(*args): print(a ...
- 清华大学OS操作系统实验lab1练习知识点汇总
lab1知识点汇总 还是有很多问题,但是我觉得我需要在查看更多资料后回来再理解,学这个也学了一周了,看了大量的资料...还是它们自己的80386手册和lab的指导手册觉得最准确,现在我就把这部分知识做 ...
- c++ 函数知识点汇总
c++ 函数知识点汇总 swap函数 交换两个数组元素 比如 swap(a[i],a[j]); 就是交换a[i] 和 a[j] 的值 strcpy() 复制一个数组元素的值到另一个数组元素里 strc ...
- 前端开发 JavaScript 干货知识点汇总
很多初学的朋友经常问我,前端JavaScript都需要学习哪些东西呀?哪些是JavaScript的重点知识啊? 其实做前端开发工程师,所有的知识点都是我们学习必备的东西,只有扎实的技术基础才是高薪的关 ...
- BBS项目知识点汇总
目录 bbs项目知识点汇总 一. JavaScript 1 替换头像 2 form表单拿数据 3 form组件error信息渲染 4 添加html代码 5 聚焦操作 二 . html在线编辑器 三 . ...
- Java面试知识点汇总
Java面试知识点汇总 置顶 2019年05月07日 15:36:18 温柔的谢世杰 阅读数 21623 文章标签: 面经java 更多 分类专栏: java 面试 Java面试知识汇总 版权声明 ...
- 离散数学 II(最全面的知识点汇总)
离散数学 II(知识点汇总) 目录 离散数学 II(知识点汇总) 代数系统 代数系统定义 例子 二元运算定义 运算及其性质 二元运算的性质 封闭性 可交换性 可结合性 可分配性 吸收律 等幂性 消去律 ...
- ECMAScript版本知识点汇总
ECMAScript版本知识点汇总 ES5 btoa.atob 对参数进行base64格式编码.解码 /** * btoa() * base64编码 * @param {string} str * @ ...
随机推荐
- NOIP2012疫情控制(二分答案+倍增+贪心)
Description H国有n个城市,这n个城市用n-1条双向道路相互连通构成一棵树,1号城市是首都,也是树中的根节点. H国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散到边境 ...
- LINUX 笔记-wc命令
命令参数: -c 统计字节数. -l 统计行数. -m 统计字符数.这个标志不能与 -c 标志一起使用. -w 统计字数.一个字被定义为由空白.跳格或换行字符分隔的字符串.
- ansible服务部署与使用
第1章 ssh+key实现基于密钥连接(ansible使用前提) 说明: ansible其功能实现基于SSH远程连接服务 使用ansible需要首先实现ssh密钥连接 1.1 部署ssh ...
- spacemacs 初始安装报错
尝试使用emcas的配置文件spacemacs,第一次安装启动时,界面为纯白色,而且在输入完几个配置选项后,报了一个错误 Symbol's value as variable is void 根据官网 ...
- Lua 5.3 协程简单示例
Lua 5.3 协程简单示例 来源 http://blog.csdn.net/vermilliontear/article/details/50547852 生产者->过滤器->消费者 模 ...
- windows下配置wampserver
第一,打开局域网访问 配置文件:点击右下角的WAMP 服务器小托盘,选择Apache>httpd.conf 搜索关键字 "deny from ",会发现一处 "de ...
- Asp.Net 为什么需要异步
之前看过别人提出为什么在本是多线程的Asp.Net下需要异步环境的时候,提出在Asp.Net环境下本身就是多线程,每个请求就是由一个专门IIS线程负责(咱不说Core下无IIS的情况).所以以此推论A ...
- CSS和文档
1. 块级元素: p,div,ul,ol,h1,h2 . . . h6等.块级元素独占一行,旁边不能有其他元素. 2. 行内元素:span,a,strong,em等. display属性可以使块级元素 ...
- 万年历java
public void showTime(){/*万年历 : 1900年1月20号是星期几?1月1号是星期一1月8号是星期一1月15号是星期一1%7 = 18%7 = 115%7 = 1★: 1. ...
- C#中泛型之Dictionary
1.命名空间:System.Collections.Generic(程序集:mscorlib)2.描述: 1).从一组键(Key)到一组值(Value)的映射,每一个添加项都是由一个值及其相关连的键组 ...