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 相关文章推荐
js验证表单大全
Nov 25 Javascript
cookie丢失问题(认证失效) Authentication (用户验证信息)也会丢失
Jun 04 Javascript
Jquey拖拽控件Draggable使用方法(asp.net环境)
Sep 28 Javascript
JS复制内容到剪切板的实例代码(兼容IE与火狐)
Nov 19 Javascript
js判断当前浏览器类型,判断IE浏览器方法
Jun 02 Javascript
jQuery异步上传文件插件ajaxFileUpload详细介绍
May 19 Javascript
JavaScript学习笔记(三):JavaScript也有入口Main函数
Sep 12 Javascript
easyui form validate总是返回false的原因及解决方法
Nov 07 Javascript
从零开始学习Node.js系列教程之基于connect和express框架的多页面实现数学运算示例
Apr 13 Javascript
angular2中router路由跳转navigate的使用与刷新页面问题详解
May 07 Javascript
详述 Sublime Text 打开 GBK 格式中文乱码的解决方法
Oct 26 Javascript
Vue2.0中三种常用传值方式(父传子、子传父、非父子组件传值)
Aug 16 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
PHP中使用gettext来支持多语言的方法
2011/05/02 PHP
php微信公众号开发之校园图书馆
2018/10/20 PHP
破解Session cookie的方法
2006/07/28 Javascript
用ASP将SQL搜索出来的内容导出为TXT的代码
2007/07/27 Javascript
IE的事件传递-event.cancelBubble示例介绍
2014/01/12 Javascript
用jQuery toggleClass 实现鼠标移上变色
2014/05/14 Javascript
Javascript中的delete操作符详细介绍
2014/06/06 Javascript
使用HTML+CSS+JS制作简单的网页菜单界面
2015/07/27 Javascript
jQuery实现的小图列表,大图展示效果幻灯片示例
2016/10/25 Javascript
javascript 实现文本使用省略号替代(超出固定高度的情况)
2017/02/21 Javascript
jQuery插件FusionCharts绘制2D双折线图效果示例【附demo源码】
2017/04/14 jQuery
详解用node搭建简单的静态资源管理器
2017/08/09 Javascript
angular 组件通信的几种实现方式
2018/07/13 Javascript
深入理解Vue 组件之间传值
2018/08/16 Javascript
JS实现的视频弹幕效果示例
2018/08/17 Javascript
微信小程序实现左右列表联动
2020/05/19 Javascript
Vue中util的工具函数实例详解
2019/07/08 Javascript
[00:50]2014DOTA2国际邀请赛 NEWBEE战队回顾
2014/08/01 DOTA
Python脚本实现集群检测和管理功能
2015/03/06 Python
Python中set与frozenset方法和区别详解
2016/05/23 Python
快速入门python学习笔记
2017/12/06 Python
python爬虫使用cookie登录详解
2017/12/27 Python
Python中pip更新和三方插件安装说明
2018/07/08 Python
Python常见内置高效率函数用法示例
2018/07/31 Python
Python根据文件名批量转移图片的方法
2018/10/21 Python
Python3监控windows,linux系统的CPU、硬盘、内存使用率和各个端口的开启情况详细代码实例
2020/03/18 Python
opencv 图像礼帽和图像黑帽的实现
2020/07/07 Python
Python Flask异步发送邮件实现方法解析
2020/08/01 Python
运行python提示no module named sklearn的解决方法
2020/11/29 Python
布鲁明戴尔百货店:Bloomingdale’s
2016/12/21 全球购物
医药专业推荐信
2013/11/15 职场文书
酒店总经理助理岗位职责
2014/02/01 职场文书
小学生五一劳动节演讲稿
2015/03/18 职场文书
CSS3通过var()和calc()函数实现动画特效
2021/03/30 HTML / CSS
Python爬虫之爬取最新更新的小说网站
2021/05/06 Python
一篇文章搞懂python混乱的切换操作与优雅的推导式
2021/08/23 Python