Fetch 的实例讲解

栏目: 后端 · 前端 · 发布时间: 5年前

内容简介:Fetch API 提供了一个 JavaScript接口,用于访问和操纵 HTTP 管道的部分,例如请求和响应。它还提供了一个全局fetch()方法,该方法提供了一种简单,合乎逻辑的方式来跨网络异步获取资源。cache 表示如何处理缓存, 遵守 http 规范, 拥有如下几种值:

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

fetch() 必须接受一个参数---路径。无论请求成功与否,它都返回一个 Promise 对象,resolve 对应请求的 Response 。另外你还可以设置第二个参数(可选的参数)(常用配置如下,具体详情参见 Request )。

配置

options={
    // 请求方式 GET,POST,等
    method: "GET", 
    
    // 请求头headers   
    headers: {
        Accept: 'application/json, text/plain, */*',
        'Content-Type': 'application/json;charset=UTF-8', 
        'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
	},
	
    // omit: 从不发送cookies.
    // same-origin 只有当URL与响应脚本同源才发送 cookies
    // include 总是发送请求资源域在本地的 cookies 验证信息
    credentials: 'include',
    
    //包含请求的模式 (例如: cors, no-cors, same-origin, navigate)
    //no-cors: 常用于跨域请求不带CORS响应头场景
    //cors表示同域和带有CORS响应头的跨域下可请求成功. 其他请求将被拒绝
    mode: 'cors',
    
    //包含请求的缓存模式 (例如: default, reload, no-cache).具体参数见下面(cache参数)
    cache: 'default'
}
复制代码

cache参数

cache 表示如何处理缓存, 遵守 http 规范, 拥有如下几种值:

  1. default: 浏览器从 HTTP 缓存中寻找匹配的请求.
  2. no-store: 浏览器在不先查看缓存的情况下从远程服务器获取资源,并且不会使用下载的资源更新缓存
  3. reload: 请求之前将忽略 http 缓存的存在, 但请求拿到响应后, 它将主动更新 http 缓存.
  4. no-cache: 如果存在缓存, 那么 fetch 将发送一个条件查询 request 和一个正常的 request , 拿到响应后, 它会更新http缓存.
  5. force-cache: 浏览器在其HTTP缓存中查找匹配的请求。
    • 如果存在匹配, 新鲜或过时 ,则将从缓存中返回。
    • 如果没有匹配,浏览器将发出正常请求,并使用下载的资源更新缓存
  6. only-if-cached: fetch 强行取缓存,( 即使缓存过期了也从缓存取). 如果没有缓存, 浏览器将返回错误

案例

这是一个比较基本的案例,这里为了看的清楚,没有处理 catch 问题 。

var url = 'https://zhidao.baidu.com/question/api/hotword?pn=1561&rn=5&t=1551165472017';
fetch(url).then(function(response) {
  return response;
}).then(function(data) {
  console.log(data);
})
复制代码

可以自己动手把这个代码直接贴到控制台中 , 这里为了防止同源策略,并且看到更详细的数据我们最好在zhidao.baidu.com 内的控制台中输入。如果在其他的页面我们应该在 fetch 方法的第二个参数中加上{ mode: "no-cors" }。为了看的更加清楚,我贴出这两种情况的打印结果,如下所示:

在zhidao.baidu.com 网页控制台输入的地址

Fetch 的实例讲解

在其他网页控制台输入的地址

Fetch 的实例讲解

我们会发现两个打印结果基本不同,首先跨域打印的结果中很多数据都是空的,另外我们也发现其中 type 也不相同,这里介绍下 response.type。

fetch请求的响应类型( response.type )为如下三种之一:

  • basic,同域下, 响应类型为 “basic”。
  • cors,跨域下,返回 cors 响应头, 响应类型为 “cors”。
  • opaque,跨域下, 服务器没有返回 cors 响应头, 响应类型为 “opaque”。

看到这里,心急的同学会发现,其实现在数据还是没有拿到,我们仅仅只是拿到了个 Response 对象。那么如何拿到数据呢?

瞧好:

var url = 'https://zhidao.baidu.com/question/api/hotword?pn=1561&rn=5&t=1551165472017';
fetch(url).then(function(response) {
  //通过 response 原型上的 json 方法拿到数据,在返回出去
  return response.json();
}).then(function(data) {
  // 接收到 data 打印出来
  console.log(data);
})
复制代码

通过 response 原型上的 json 方法拿到数据,在返回出去。response 原型打印如下:

Fetch 的实例讲解

这里要注意的是 response .json / response.text 方法只能使用一个并且只能使用一次,同时使用两个,或则使用两次都会报如下错误:

Uncaught (in promise) TypeError: Failed to execute 'json' on 'Response': body stream is locked

为什么不能使用两次?

数据流只能读取一次,一旦读取,数据流变空,再次读取会报错。可以使用 response.clone() 复制一个副本。

为什么只能读取一次?

答案还在查寻中,同时也希望知道的读者能够指点一下。

上面的写法,看起来有回调,又有链式调用,我们试着换个新写法,这里使用 async/await 来实现:

var url = 'https://zhidao.baidu.com/question/api/hotword?pn=1&rn=5&t=1551191647420';
let getData = async () => {
    let response = await fetch(url);
    let data = response.json();
    console.log(data)
}
复制代码

打印 data 如下:

Fetch 的实例讲解

这里 data 是一个 Promise 对象,由于他的内部变量[[PromiseValue]]在外部无法得到,只能在 then 中获取,所以在后面加上 then 获取 data

let response = await fetch(url);
let data = response.json();
data.then((res)=>{
  console.log(res)
})
// 搞定 res 就是我们要的数据拉
复制代码

封装

我们通过 fetch 来做个简易的 request 封装,顺便把 options 再回顾一遍,很多配置在实际中可能是不需要的,都有默认配置(options 的默认配置在下面括号中)。

function request(url, data = {}) {
  // options配置的默认选项在括号中
    return fetch(url, {
        method: "POST", //(GET), POST, PUT, DELETE, etc
        mode: "cors", // (same-origin), no-cors, cors
        cache: "no-cache", // (default), no-cache, reload, force-cache, only-if-cached
        credentials: "same-origin", //(same-origin), include, omit
        headers: {
            "Content-Type": "application/json",
            // "Content-Type": "application/x-www-form-urlencoded",
        },
        redirect: "follow", //(follow), manual, error
        referrer: "no-referrer", //(client), no-referrer
        body: JSON.stringify(data), // 这里格式要与 "Content-Type" 同步
    })
    .then(response => response.json());
}
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

人件(原书第3版)

人件(原书第3版)

[美] Tom DeMarco、[美] Timothy Lister / 肖然、张逸、滕云 / 机械工业出版社 / 2014-8 / 69.00元

在软件管理领域,很少有著作能够与本书媲美。作为经久不衰的畅销书,本书深刻地洞察到软件开发的最大问题不在于技术,而在于人。人的因素并不容易解决,一旦解决了,你将更有可能获得成功。 本书是软件管理领域的传奇经典,被誉为“对美国软件业影响最大的一本书”。全书从管理人力资源、创建健康的办公环境、雇用并留用正确的人、高效团队形成、改造企业文化和快乐工作等多个角度阐释了如何思考和管理软件开发的最大问题—......一起来看看 《人件(原书第3版)》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具