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中的数学函数
Apr 04 Javascript
jquery实现隐藏与显示动画效果/输入框字符动态递减/导航按钮切换
Jul 01 Javascript
js如何获取object类型里的键值
Feb 18 Javascript
使用jquery写个更改表格行顺序的小功能
Apr 29 Javascript
IE8 内存泄露(内存一直增长 )的原因及解决办法
Apr 06 Javascript
【经验总结】编写JavaScript代码时应遵循的14条规律
Jun 20 Javascript
Vue.js快速入门教程
Sep 07 Javascript
利用webstrom调试Vue.js单页面程序的方法教程
Jun 06 Javascript
基于JavaScript实现抽奖系统
Jan 16 Javascript
vue-router配合ElementUI实现导航的实例
Feb 11 Javascript
js作用域和作用域链及预解析
Apr 11 Javascript
jQuery实现的记住帐号密码功能完整示例
Aug 03 jQuery
详解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
PHP借助phpmailer发送邮件
2015/05/11 PHP
PHP全功能无变形图片裁剪操作类与用法示例
2017/01/10 PHP
PHP7移除的扩展和SAPI
2021/03/09 PHP
20个非常棒的Jquery实用工具 国外文章
2010/01/01 Javascript
用Juery网页选项卡实现代码
2011/06/13 Javascript
jquery获得keycode的示例代码
2013/12/30 Javascript
Angularjs中UI Router全攻略
2016/01/29 Javascript
js实现当鼠标移到表格上时显示这一格全部内容的代码
2016/06/12 Javascript
微信小程序中使用ECharts 异步加载数据的方法
2018/06/27 Javascript
浅谈关于iview表单验证的问题
2018/09/29 Javascript
小试小程序云开发(小结)
2019/06/06 Javascript
Python使用ntplib库同步校准当地时间的方法
2016/07/02 Python
今天 平安夜 Python 送你一顶圣诞帽 @微信官方
2017/12/25 Python
浅谈Python中重载isinstance继承关系的问题
2018/05/04 Python
解决python selenium3启动不了firefox的问题
2018/10/13 Python
Python3 jupyter notebook 服务器搭建过程
2018/11/30 Python
python 检查文件mime类型的方法
2018/12/08 Python
python实现浪漫的烟花秀
2019/01/30 Python
python实现登录密码重置简易操作代码
2019/08/14 Python
PyTorch中Tensor的拼接与拆分的实现
2019/08/18 Python
Python操作Word批量生成合同的实现示例
2020/08/28 Python
HTML5 实战PHP之Web页面表单设计
2011/10/09 HTML / CSS
国外平面设计素材网站:The Hungry JPEG
2017/03/28 全球购物
介绍一下Java的安全机制
2012/06/28 面试题
EntityManager都有哪些方法
2013/11/01 面试题
办公室秘书自我鉴定
2014/01/18 职场文书
继承公证书样本
2014/04/04 职场文书
走群众路线剖析材料
2014/10/09 职场文书
泸县召开党的群众路线教育实践活动总结大会新闻稿
2014/10/21 职场文书
课文《燕子》教学反思
2016/02/17 职场文书
学生安全责任协议书
2016/03/22 职场文书
古诗之爱国古诗5首
2019/09/20 职场文书
go语言中json数据的读取和写出操作
2021/04/28 Golang
用Python将GIF动图分解成多张静态图片
2021/06/11 Python
Python学习开发之图形用户界面详解
2021/08/23 Python
Java处理延时任务的常用几种解决方案
2022/06/01 Java/Android