前面的话

  Fetch API 提供了一个 JavaScript接口,用于访问和操纵HTTP管道的部分,例如请求和响应。它还提供了一个全局 fetch()方法,该方法提供了一种简单,合乎逻辑的方式来跨网络异步获取资源。本文将详细介绍fetch的相关内容

概述

  跨网络异步获取资源的功能以前是使用 XMLHttpRequest实现的。Fetch提供了一个更好的替代方法,可以很容易地被其他技术使用,例如 Service Workers。Fetch还提供了单个逻辑位置来定义其他HTTP相关概念,例如 CORS和HTTP的扩展

  fetch 规范与 jQuery.ajax() 主要有两种方式的不同

  1、当接收到一个代表错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即使该 HTTP 响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok 属性设置为 false ), 仅当网络故障时或请求被阻止时,才会标记为 reject

  2、默认情况下, fetch 不会从服务端发送或接收任何 cookies,如果站点依赖于用户 session,则会导致未经认证的请求(要发送 cookies,必须设置 credentials 选项)

fetch请求

  一个基本的 fetch请求设置起来很简单。这里我们通过网络获取一个图像并将其插入到一个 <img> 元素中。最简单的用法是只提供一个参数用来指明想fetch到的资源路径,然后返回一个包含响应结果的promise(一个 Response 对象)

  1. let myImage = document.querySelector('img');
  2.  
  3. fetch('flowers.jpg')
  4. .then(function(response) {
  5. return response.blob();
  6. })
  7. .then(function(myBlob) {
  8. let objectURL = URL.createObjectURL(myBlob);
  9. myImage.src = objectURL;
  10. });

自定义参数

  fetch() 接受第二个可选参数,一个可以控制不同配置的 init 对象:

  1. var myHeaders = new Headers();
  2.  
  3. var myInit = { method: 'GET',
  4. headers: myHeaders,
  5. mode: 'cors',
  6. cache: 'default' };
  7.  
  8. fetch('flowers.jpg',myInit)
  9. .then(function(response) {
  10. return response.blob();
  11. })
  12. .then(function(myBlob) {
  13. var objectURL = URL.createObjectURL(myBlob);
  14. myImage.src = objectURL;
  15. });

post

  1. // 通过fetch获取百度的错误提示页面
  2. fetch('https://www.baidu.com/search/error.html', {
  3. method: 'POST',
  4. body: JSON.stringify({a:}),
  5.   headers: { ...new Headers(headers), 'Content-Type': 'application/json' }
  6. })
  7. .then((res)=>{
  8. return res.text()
  9. })
  10. .then((res)=>{
  11. console.log(res)
  12. })

JSON数据

  1. // 通过fetch获取百度的错误提示页面
  2. fetch('https://www.baidu.com/rec?platform=wise&ms=1&rset=rcmd&word=123&qid=11327900426705455986&rq=123&from=844b&baiduid=A1D0B88941B30028C375C79CE5AC2E5E%3AFG%3D1&tn=&clientWidth=375&t=1506826017369&r=8255', { // 在URL中写上传递的参数
  3. method: 'GET',
  4. headers: new Headers({
  5. 'Accept': 'application/json' // 通过头指定,获取的数据类型是JSON
  6. })
  7. })
  8. .then((res)=>{
  9. return res.json() // 返回一个Promise,可以解析成JSON
  10. })
  11. .then((res)=>{
  12. console.log(res) // 获取JSON数据
  13. })

检测成功

  如果遇到网络故障,fetch() promise 将会 reject,带上一个 TypeError 对象。虽然这个情况经常是遇到了权限问题或类似问题——比如 404 不是一个网络故障。想要精确的判断 fetch() 是否成功,需要包含 promise resolved 的情况,此时再判断 Response.ok 是不是为 true

  1. fetch('flowers.jpg').then(function(response) {
  2. if(response.ok) {
  3. response.blob().then(function(myBlob) {
  4. var objectURL = URL.createObjectURL(myBlob);
  5. myImage.src = objectURL;
  6. });
  7. } else {
  8. console.log('Network response was not ok.');
  9. }
  10. })
  11. .catch(function(error) {
  12. console.log('There has been a problem with your fetch operation: ' + error.message);
  13. });

Headers

  使用 Headers 的接口,可以通过 Headers() 构造函数来创建一个自己的 headers 对象。一个 headers 对象是一个简单的多名值对:

  1. var content = "Hello World";
  2. var myHeaders = new Headers();
  3. myHeaders.append("Content-Type", "text/plain");
  4. myHeaders.append("Content-Length", content.length.toString());
  5. myHeaders.append("X-Custom-Header", "ProcessThisImmediately");

  也可以传一个多维数组或者对象字面量:

  1. myHeaders = new Headers({
  2. "Content-Type": "text/plain",
  3. "Content-Length": content.length.toString(),
  4. "X-Custom-Header": "ProcessThisImmediately",
  5. });

  它的内容可以被获取:

  1. console.log(myHeaders.has("Content-Type")); // true
  2. console.log(myHeaders.has("Set-Cookie")); // false
  3. myHeaders.set("Content-Type", "text/html");
  4. myHeaders.append("X-Custom-Header", "AnotherValue");
  5.  
  6. console.log(myHeaders.get("Content-Length")); //
  7. console.log(myHeaders.getAll("X-Custom-Header")); // ["ProcessThisImmediately", "AnotherValue"]
  8.  
  9. myHeaders.delete("X-Custom-Header");
  10. console.log(myHeaders.getAll("X-Custom-Header")); // [ ]

封装

  下面是笔者在react中对fetch的精简版封装

  1. import { showLoading, hideLoading, showAlertText, hideAlertText } from '@/components/Alert/module'
  2. import { logout } from '@/components/Auth/module'
  3.  
  4. const async = ({ dispatch, url, method, data, headers, success, fail, doHideAlert }) => {
  5. // 显示loading
  6. dispatch(showLoading())
  7. let fetchObj = {}
  8. if (method) {
  9. fetchObj = {
  10. method,
  11. body: JSON.stringify(data),
  12. headers: new Headers({ ...headers, 'Content-Type': 'application/json' })
  13. }
  14. }
  15. fetch(url, fetchObj).then(res => {
  16. // 关闭loading
  17. dispatch(hideLoading())
  18. return res.json()
  19. }).then(json => {
  20. // 成功
  21. if (json.code === ) {
  22. !doHideAlert && dispatch(showAlertText(json.message))
  23. setTimeout(() => {
  24. dispatch(hideAlertText())
  25. }, )
  26. success && success(json.result)
  27. // 自定义错误
  28. } else if (json.code === ) {
  29. dispatch(showAlertText(json.message))
  30. // 系统错误
  31. } else if (json.code === ) {
  32. dispatch(showAlertText(json.message))
  33. fail && fail(json.err)
  34. // 认证失败
  35. } else if (json.code === ) {
  36. dispatch(showAlertText(json.message))
  37. dispatch(logout)
  38. }
  39. }).catch(() => {
  40. dispatch(showAlertText('服务器故障'))
  41. })
  42. }
  43.  
  44. export default async

fetch简明学习的更多相关文章

  1. WebPack 简明学习教程

    WebPack 简明学习教程 字数1291 阅读22812 评论11 喜欢35 WebPack是什么 一个打包工具 一个模块加载工具 各种资源都可以当成模块来处理 网站 http://webpack. ...

  2. redux简明学习

    前面的话 这几天被redux折腾的够呛,看了很多视频,也看了很多资料.很多时候,感觉好像顿悟了,但实际上只是理解了其中的一个小概念而已.真正去做项目的时候,还是会卡壳.可能是学CSS和Javascri ...

  3. react-router简明学习

    前面的话 路由用来分发请求.后端是提供服务的,所以它的路由是在找controller,前端是显示页面的,所以它的路由是在找component.本文将详细介绍react-router-dom的内容 Ro ...

  4. Java8简明学习之Lambda表达式

    函数式接口 就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口,函数式接口可以被隐式转换为lambda表达式. 之前已有的函数式接口: java.lang.Runnable java.uti ...

  5. redux 简明学习

    核心概念 redux专注于状态管理,把所有的状态都存在一个对象中.核心概念包括:store.state.action.reducer [store] store是保存数据的地方,redux提供crea ...

  6. (转)JMS简明学习教程

    转:http://www.cnblogs.com/jjj250/archive/2012/08/08/2628552.html 基础篇 JMS是应用系统或组件之间相互通信的应用程序接口,利用它,我们可 ...

  7. HTML标签简明学习一

    !-- ... -- html注释 浏览器不对其中的内容解析,可以用来调试及书写释意 <!-- 动不动就被注释 --> !DOCTYPE 声明文件类型 一般大写,必须位于文档首行,浏览器根 ...

  8. php简明学习笔记

    1.变量 <?php //变量声明(php变量无需单独创建,变量会在第一次赋值时创建) $a = 1; //弱类型(php变量会根据其值自动转换为相应的数据类型) $a = "a&qu ...

  9. React简明学习

    前面的话 React让组件化成为了前端开发的基本思路,比传统思路可以更好的控制前端复杂度,旧的开发方法受到了影响,如分离式的HTML/CSS.非侵入式JS.模板语言.MVC.CSS文件.Bootstr ...

随机推荐

  1. 关于Cesium中的常用坐标系及说明

    Cesium是一个基于JavaScript的开源框架,可用于在浏览器中绘制3D的地球,并在其上绘制地图(支持多种格式的瓦片服务),该框架不需要任何插件支持,但是浏览器必须支持WebGL. Cesium ...

  2. 在java或 js中的日期时间转换问题

    1.在js中需要求的当前日期的周一和周日 var now = new Date(); // 当前日期时间对象 var date = now.getDate(); // 当前是几号:当前日期在一个月中的 ...

  3. vue+webpack+element-ui+git

    webpack.config.jsconst { resolve } = require('path') const webpack = require('webpack') const HtmlWe ...

  4. Redis 中的数据类型及基本操作

    Redis 内置的数据类型有 5种:字符串String.哈希Hash.列表List.集合Set.有序集合ZSet 字符串类型 String 是 Redis 中最基本的类型,一个 key 对应着一个 v ...

  5. docker部署PMA(LNMP架构)

    上篇文章中已经部署好php环境,测试也已经OK centos 7 docker 启动了一个web服务 但是启动时 报 WARNING: IPv4 forwarding is disabled. Net ...

  6. echarts词云引用

    最近项目中需要使用echarts的词云图,因为几经波折才引用成功,所以想记下来跟大家分享,(我的随笔不会写那么多让人需要动脑子去理解的东西,就是记录一下步骤,因为经验甚少,底层原理懂得不多,所以就先记 ...

  7. 多线程使用Lock实现生产者实现者代码

    package cn.com.servyou.qysdsjx.thread; import java.util.ArrayList; import java.util.List; import jav ...

  8. Suricata 之IPS模式

    IPS 1.Suricata 本身是不具有拦截功能的,想要让它拦截包需要配合 iptables 使用. 首先要确定安装的suricata是否支持IPS模式,如果在安装编译的时候没有启用IPS模式,NF ...

  9. CSS3动画箭头

    <style type="text/css"> .arrow { display: block; width: 20px; height: 20px; position ...

  10. 笔试常考--浏览器兼容性问题及解决方案(CSS)

    问题一:不同浏览器的标签默认的外补丁和内补丁不同 问题现象:随便写几个标签,不加样式控制的情况下,各自的margin 和padding差异较大. 解决方案:css里加: ;;} 备注:这个是最常见的也 ...