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图片阅览组件
Nov 09 Javascript
JS 屏蔽键盘不可用与鼠标右键不可用的方法
Nov 18 Javascript
js的toLowerCase方法用法实例
Jan 27 Javascript
JavaScript使用yield模拟多线程的方法
Mar 19 Javascript
js实现的tab标签切换效果代码分享
Aug 25 Javascript
javascript类型系统 Window对象学习笔记
Jan 07 Javascript
jQuery实现页面评论栏中访客信息自动填写功能的方法
May 23 Javascript
微信小程序 支付功能(前端)的实现
May 24 Javascript
修改vue+webpack run build的路径方法
Sep 01 Javascript
基于Fixed定位的框选功能的实现代码
May 13 Javascript
npm ci命令的基本使用方法
Sep 20 Javascript
vue 插槽简介及使用示例
Nov 19 Vue.js
详解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实现执行某一操作时弹出确认、取消对话框
2013/12/30 PHP
ext监听事件方法[初级篇]
2008/04/27 Javascript
JS 中document.URL 和 windows.location.href 的区别
2009/11/11 Javascript
javascript 动态设置已知select的option的value值的代码
2009/12/16 Javascript
JavaScript 学习笔记(六)
2009/12/31 Javascript
jQuery阻止事件冒泡具体实现
2013/10/11 Javascript
js showModalDialog弹出窗口实例详解
2014/01/07 Javascript
jQuery实现自定义事件的方法
2015/04/17 Javascript
JS实现动态移动层及拖动浮层关闭的方法
2015/04/30 Javascript
jQuery超酷平面式时钟效果代码分享
2020/03/30 Javascript
iframe中子父类窗口调用JS的方法及注意事项
2015/08/25 Javascript
jQuery实现简单滚动动画效果
2016/04/07 Javascript
新手学习前端之js模仿淘宝主页网站
2016/10/31 Javascript
浅析使用BootStrap TreeView插件实现灵活配置快递模板
2016/11/28 Javascript
微信小程序使用image组件显示图片的方法【附源码下载】
2017/12/08 Javascript
Vue下滚动到页面底部无限加载数据的示例代码
2018/04/22 Javascript
Nodejs异步回调之异常处理实例分析
2018/06/22 NodeJs
Bootstrap Table中的多选框删除功能
2018/07/15 Javascript
jQuery实现轮播图源码
2019/10/23 jQuery
全网小程序接口请求封装实例代码
2020/11/06 Javascript
实例讲解python函数式编程
2014/06/09 Python
python使用Berkeley DB数据库实例
2014/09/26 Python
pandas 获取季度,月度,年度首尾日期的方法
2018/04/11 Python
python excel使用xlutils类库实现追加写功能的方法
2018/05/02 Python
快速解决vue.js 模板和jinja 模板冲突的问题
2019/07/26 Python
python GUI库图形界面开发之PyQt5中QMainWindow, QWidget以及QDialog的区别和选择
2020/02/26 Python
Python如何操作office实现自动化及win32com.client的运用
2020/04/01 Python
如何学习Python time模块
2020/06/03 Python
联想香港官方网站及网店:Lenovo香港
2018/04/13 全球购物
C++面试题:关于链表和指针
2013/06/05 面试题
8和9的加减法教学反思
2014/05/01 职场文书
年度评优评先方案
2014/06/03 职场文书
2014年班务工作总结
2014/12/02 职场文书
优秀党员事迹材料
2014/12/18 职场文书
2015年秋季开学典礼校长致辞
2015/07/16 职场文书
浅谈GO中的Channel以及死锁的造成
2022/03/18 Golang