vue项目中使用fetch的实现方法


Posted in Javascript onApril 25, 2019

fetch的由来和定义

fetch的由来     

众所周知,传统 Ajax (指 XMLHttpRequest)是最早出现的发送异步请求技术,其核心是使用XMLHttpRequest对象。但是它也存在一些令人头疼的问题:XHR 是一个设计粗糙的 API,不符合关注分离的原则;配置和调用方式非常混乱,而且基于事件的异步模型写起来也没有现代的 Promise,generator/yield,async/await 友好。而Fetch 的出现就是为了解决 XHR 存在的问题。

fetch的定义和使用

MDN中的描述:  

Fetch API 提供了一个获取资源的接口(包括跨域请求)。任何使用过 XMLHttpRequest 的人都能轻松上手,但新的API提供了更强大和灵活的功能集。but 因为凄惨的兼容性,让这个东东用起来比较困难。那我可以自己封装一下,对于不支持fetch的浏览器便使用ajax 代替(见下文)。      

Fetch 的核心在于对 HTTP 接口的抽象,包括 Request,Response,Headers,Body,以及用于初始化异步请求的 global fetch。其中,global fetch方法的语法定义:

fetch(input[, init]); 

input:定义要获取的资源。可以是一个资源的 URL 字符串,也可以是一个 Request 对象。
init:可选,一个配置项对象,包括所有对请求的设置。包括:method,headers,body,mode,credentials等返回值:Promise     

切记一点:Fetch是基于promise设计的,它不是ajax的进一步封装,而是原生js API,没有使用XMLHttpRequest对象。

fetch的优点和缺点

优点:

1. 语法简洁,更加语义化
2. 基于标准 Promise 实现,支持 async/await
3. 同构方便,更加底层,提供的API丰富(request, response, body , headers)5. 脱离了XHR,是ES规范里新的实现方式

缺点:

1. fetch只对网络请求报错,对400,500都当做成功的请求,服务器返回 400,500 错误码时并不会 reject。
2. fetch默认不会带cookie,需要添加配置项: credentials: 'include'。
3. fetch不支持abort,不支持超时控制,造成了流量的浪费。
4. fetch没有办法原生监测请求的进度,而XHR可以

补充知识点:

Fetch的mode配置项有3个取值:   

same-origin:该模式是不允许跨域的,它需要遵守同源策略;   

cors: 该模式支持跨域请求,顾名思义它是以CORS的形式跨域;

no-cors: 该模式用于跨域请求但是服务器不带CORS响应头,也就是服务端不支持CORS;目前,针对跨域请求,cors模式是常见的实现。

vue项目中完美封装fetch

话不多少,直接附上代码。

env.js文件,如下:

/** 
* baseUrl: 域名地址 
* routerMode: 路由模式
*/

let baseUrl = '';
let routerMode = 'history';
if (process.env.NODE_ENV == 'development') { 
  baseUrl = 'http://localhost:3000';
}else{ 
  baseUrl = 'http://xxxx这里是线上地址xxx';
}

export { baseUrl, routerMode }

fetch.js文件,如下:

import { baseUrl } from './env'
export default async(url = '', data = {}, type = 'GET', method = 'fetch') => {
 type = type.toUpperCase();
 url = baseUrl + url;

    // 此处规定get请求的参数使用时放在data中,如同post请求
 if (type == 'GET') {
 let dataStr = ''; 
 Object.keys(data).forEach(key => {
  dataStr += key + '=' + data[key] + '&';
 })
 
 if (dataStr !== '') {
  dataStr = dataStr.substr(0, dataStr.lastIndexOf('&'));
  url = url + '?' + dataStr;
 }
 }

    // 对于支持fetch方法的浏览器,处理如下:
 if (window.fetch && method == 'fetch') {
 let requestConfig = {
            // fetch默认不会带cookie,需要添加配置项credentials允许携带cookie
  credentials: 'include', 
  method: type,
  headers: {
  'Accept': 'application/json',
  'Content-Type': 'application/json'
  },
  mode: "cors", // 以CORS的形式跨域
  cache: "force-cache"
 }
 
 if (type == 'POST') {
  Object.defineProperty(requestConfig, 'body', {
  value: JSON.stringify(data)
  })
 }
 
 try {
  const response = await fetch(url, requestConfig);
  const responseJson = await response.json();
  return responseJson
 } catch (error) {
  throw new Error(error)
 }
 } else { // 对于不支持fetch的浏览器,便自动使用 ajax + promise
 return new Promise((resolve, reject) => {
  let requestObj;
  if (window.XMLHttpRequest) {
  requestObj = new XMLHttpRequest();
  } else {
  requestObj = new ActiveXObject; // 兼容IE
  }
 
  let sendData = '';
  if (type == 'POST') {
  sendData = JSON.stringify(data);
  }
 
  requestObj.open(type, url, true);
  requestObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  requestObj.send(sendData);
 
  requestObj.onreadystatechange = () => {
  if (requestObj.readyState == 4) {
   if (requestObj.status == 200) {
   let obj = requestObj.response
   if (typeof obj !== 'object') {
    obj = JSON.parse(obj);
   }
   resolve(obj)
   } else {
   reject(requestObj)
   }
  }
  }
 })
 }
}

以上代码,亲测有效。Over, thanks !希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
编写可维护面向对象的JavaScript代码[翻译]
Feb 12 Javascript
js判断60秒以及倒计时示例代码
Jan 24 Javascript
使用node+vue.js实现SPA应用
Jan 28 Javascript
jquery实现页面常用的返回顶部效果
Mar 04 Javascript
jquery插件格式实例分析
Jun 16 Javascript
js验证真实姓名与身份证号,手机号的简单实例
Jul 18 Javascript
全面了解JavaScript对象进阶
Jul 19 Javascript
Extjs gridpanel 中的checkbox(复选框)根据某行的条件不能选中的解决方法
Feb 17 Javascript
简单实现AngularJS轮播图效果
Apr 10 Javascript
es7学习教程之fetch解决异步嵌套问题的方法示例
Jul 21 Javascript
AngularJS中filter的使用实例详解
Aug 25 Javascript
详解vue-flickity的fullScreen功能实现
Apr 07 Javascript
详解vuejs2.0 select 动态绑定下拉框支持多选
Apr 25 #Javascript
微信小程序遍历Echarts图表实现多个饼图
Apr 25 #Javascript
在微信小程序中使用图表的方法示例
Apr 25 #Javascript
详解VUE Element-UI多级菜单动态渲染的组件
Apr 25 #Javascript
WebGL three.js学习笔记之阴影与实现物体的动画效果
Apr 25 #Javascript
WebGL学习教程之Three.js学习笔记(第一篇)
Apr 25 #Javascript
Angular封装搜索框组件操作示例
Apr 25 #Javascript
You might like
咖啡豆分级制度 咖啡豆等级分类 咖啡豆是按口感分类的吗?
2021/03/05 新手入门
php笔记之:php数组相关函数的使用
2013/04/26 PHP
PHP实现简单搜歌的方法
2015/07/28 PHP
PHP基于curl实现模拟微信浏览器打开微信链接的方法示例
2019/02/15 PHP
Laravel框架源码解析之反射的使用详解
2020/05/14 PHP
动态载入js提高网页打开速度的方法
2014/07/04 Javascript
js获取微信版本号的方法
2015/05/12 Javascript
JS实现最简单的冒泡排序算法
2017/02/15 Javascript
BootStrap 表单控件之单选按钮水平排列
2017/05/23 Javascript
AngularJs定时器$interval 和 $timeout详解
2017/05/25 Javascript
微信小程序显示下拉列表功能【附源码下载】
2017/12/12 Javascript
jQuery EasyUI 选项卡面板tabs的使用实例讲解
2017/12/25 jQuery
你可能不知道的前端算法之文字避让(inMap)
2018/01/12 Javascript
axios 封装上传文件的请求方法
2018/09/26 Javascript
vue-cli3添加模式配置多环境变量的方法
2019/06/05 Javascript
json 带斜杠时如何解析的实现
2019/08/12 Javascript
[01:03:22]LGD vs OG 2018国际邀请赛淘汰赛BO3 第一场 8.25
2018/08/29 DOTA
python数组过滤实现方法
2015/07/27 Python
python文件名和文件路径操作实例
2017/09/29 Python
100行python代码实现跳一跳辅助程序
2018/01/15 Python
Python线性方程组求解运算示例
2018/01/17 Python
Python 获得命令行参数的方法(推荐)
2018/01/24 Python
matplotlib调整子图间距,调整整体空白的方法
2018/08/03 Python
python 检查文件mime类型的方法
2018/12/08 Python
python的slice notation的特殊用法详解
2019/12/27 Python
Python多线程Threading、子线程与守护线程实例详解
2020/03/24 Python
Python 操作 MySQL数据库
2020/09/18 Python
New Balance波兰官方商城:始于1906年,百年慢跑品牌
2017/08/15 全球购物
GANT葡萄牙官方商店:拥有美国运动服传统的生活方式品牌
2018/10/18 全球购物
俄罗斯鲜花递送:AMF
2020/04/24 全球购物
初中政治教学反思
2014/01/17 职场文书
北京奥运会主题口号
2014/06/13 职场文书
爱的奉献演讲稿
2014/09/10 职场文书
公务员四风问题对照检查材料整改措施
2014/09/26 职场文书
迎新生欢迎词
2015/01/23 职场文书
Redis超详细讲解高可用主从复制基础与哨兵模式方案
2022/04/07 Redis