使用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知识点汇总的更多相关文章

  1. nginx几个知识点汇总

    WHY? 为什么用Nginx而不用LVS? 7点理由足以说明一切:1 .高并发连接: 官方测试能够支撑 5 万并发连接,在实际生产环境中跑到 2 - 3 万并发连接数.?2 .内存消耗少: 在 3 万 ...

  2. python全栈开发 * 10知识点汇总 * 180612

    10 函数进阶 知识点汇总 一.动态参数 形参的第三种1.动态接收位置传参 表达:*args (在参数位置编写 * 表⽰接收任意内容) (1)动态位置参数def eat(*args): print(a ...

  3. 清华大学OS操作系统实验lab1练习知识点汇总

    lab1知识点汇总 还是有很多问题,但是我觉得我需要在查看更多资料后回来再理解,学这个也学了一周了,看了大量的资料...还是它们自己的80386手册和lab的指导手册觉得最准确,现在我就把这部分知识做 ...

  4. c++ 函数知识点汇总

    c++ 函数知识点汇总 swap函数 交换两个数组元素 比如 swap(a[i],a[j]); 就是交换a[i] 和 a[j] 的值 strcpy() 复制一个数组元素的值到另一个数组元素里 strc ...

  5. 前端开发 JavaScript 干货知识点汇总

    很多初学的朋友经常问我,前端JavaScript都需要学习哪些东西呀?哪些是JavaScript的重点知识啊? 其实做前端开发工程师,所有的知识点都是我们学习必备的东西,只有扎实的技术基础才是高薪的关 ...

  6. BBS项目知识点汇总

    目录 bbs项目知识点汇总 一. JavaScript 1 替换头像 2 form表单拿数据 3 form组件error信息渲染 4 添加html代码 5 聚焦操作 二 . html在线编辑器 三 . ...

  7. Java面试知识点汇总

    Java面试知识点汇总 置顶 2019年05月07日 15:36:18 温柔的谢世杰 阅读数 21623 文章标签: 面经java 更多 分类专栏: java 面试 Java面试知识汇总   版权声明 ...

  8. 离散数学 II(最全面的知识点汇总)

    离散数学 II(知识点汇总) 目录 离散数学 II(知识点汇总) 代数系统 代数系统定义 例子 二元运算定义 运算及其性质 二元运算的性质 封闭性 可交换性 可结合性 可分配性 吸收律 等幂性 消去律 ...

  9. ECMAScript版本知识点汇总

    ECMAScript版本知识点汇总 ES5 btoa.atob 对参数进行base64格式编码.解码 /** * btoa() * base64编码 * @param {string} str * @ ...

随机推荐

  1. UVa 1608,Non-boring sequences

    好诡异的一个题啊 紫书上关于从左边找还是从两边往中间找的讨论没有看懂,怎么一下就找到唯一的元素了(⊙_⊙?) 方法就是用的书上讲的方法,类似于uva 11572,不过这个题需要预处理存下两边的最近的相 ...

  2. mysql的并发处理机制_下篇

        MySQL的并发处理机制,有MVCC及锁机制来处理,上篇简要说明了 MVCC及隔离级别,这篇来说说mysql下的锁.     温馨提示:下文有几个表格长度较长,右下角的博文导航目录会挡道,浏览 ...

  3. Linux入门(5)——Ubuntu16.04安装网易云音乐

    去网易云音乐官网下载deb包: http://music.163.com/#/download 打开终端: cd 下载 .0_amd64_ubuntu16..deb sudo apt-get -f i ...

  4. Apache常用配置

    Apache配置文件:conf/httpd.conf.(注意:表示路径时使用‘/’而不使用‘\’,注释使用‘#’) 1. ServerRoot:服务器根目录,也就是Apache的安装目录,其他的目录配 ...

  5. IntelliJ IDEA创建多模块依赖项目

    刚从Eclipse转IDEA, 所以记录一下IDEA的使用 创建多模块依赖项目 1. 新建父工程 这样就创建好了一个普通项目,一般我们会把src删掉,在此项目下新建新的模块 2. 新建子模块 创建供前 ...

  6. 项目swift的一些问题

    在用swift做项目的时候,总会把之前oc的思想转过来. 1. 对Alamofire的再次封装,之前使用AFNetwork进行了在次封装,这样做的好处就是可以用一个全局的类来管理全部的网络请求,这样就 ...

  7. Element ui表格展示多张图片问题

    显示一张图片的方法: <el-table-column label="头像" width="100"> <template scope=&qu ...

  8. python、java和php的百度指数对比

    Python: Python是纯粹的自由软件, 源代码和解释器CPython遵循 GPL(GNU General Public License)协议.Python语法简洁清晰,特色之一是强制用空白符( ...

  9. Problem F

    Problem Description "Yakexi, this is the best age!" Dong MW works hard and get high pay, h ...

  10. AngularJS学习篇(五)

    AngularJS Scope(作用域) Scope(作用域) 是应用在 HTML (视图) 和 JavaScript (控制器)之间的纽带. Scope 是一个对象,有可用的方法和属性. Scope ...