本文翻译自 Intercepting JavaScript Fetch API requests and responses

拦截器是可用于预处理或后处理 HTTP 请求的代码块,有助于全局错误处理、身份验证、日志记录等。在本文中,你将学习如何拦截 JavaScript Fetch API 请求

拦截 HTTP 请求一般有两种事件:请求和响应事件。请求拦截器应该在发送实际 HTTP 请求之前执行,而响应拦截器应该在到达发出请求的应用程序代码之前执行。

在深入研究代码之前,我们需要了解一些重要的事情。首先,Fetch API 本身不支持拦截器。其次,在 Node.js 中使用 Fetch API 需要额外的包。

JavaScript Fetch API

首先,让我们介绍一些 Fetch API 的基础,例如语法:

const fetchResponsePromise = fetch(resource [, init])

resource 定义要获取的资源,该资源可以是 Request 对象,也可以是 URL。init 是一个可选对象,它将包含你想应用于此特定请求的任何自定义配置。

Fetch API 是基于 Promise 的。因此,当你调用 Fetch 方法时,你将得到一个 Promise 响应。在这里,它被称为 fetchResponsePromise,如上面的示例所示。

默认情况下,Fetch 使用 GET 方法调用 API,如下所示:

fetch('https://jsonplaceholder.typicode.com/todos/1')
.then((response) => response.json())
.then((json) => console.log(json));

下面是一个使用 Fetch 发送 POST 请求的示例:

fetch('https://jsonplaceholder.typicode.com/todos', {
method: 'POST',
body: JSON.stringify({
completed: false,
id: 1,
title: 'New Todo',
userId: 1,
}),
headers: new Headers({
'Content-Type': 'application/json; charset=UTF-8',
}),
})
.then((response) => response.json())
.then((json) => console.log(json));

POST 请求必须有 body。 查看 Fetch 文档 了解更多详细信息。

实现拦截

有两种方法可以在 Fetch API 请求时添加拦截器:使用猴子补丁或者使用库 fetch-intercept

对 Fetch 使用猴子补丁(monkey patching)

为任何 JavaScript 函数或方法创建拦截器的一种方法是对其进行猴子修补。猴子补丁是一种用自己的函数版本覆盖原始函数的方法。

让我们一步一步地看看如何使用猴子补丁为 Fetch API 创建拦截器:

const { fetch: originalFetch } = window;

window.fetch = async (...args) => {
let [resource, config ] = args;
// request interceptor here
const response = await originalFetch(resource, config);
// response interceptor here
return response;
};

上面的代码使用自定义实现重写原始 Fetch 方法,并在其中调用原始 Fetch 方法。你可以使用这个样例代码来创建请求和响应拦截器。

请求拦截器

在下面的示例中,我们将创建一个简单的请求拦截器,用于更改一个请求示例的 URL:

const { fetch: originalFetch } = window;
window.fetch = async (...args) => {
let [resource, config ] = args; // request interceptor starts
resource = 'https://jsonplaceholder.typicode.com/todos/2';
// request interceptor ends const response = await originalFetch(resource, config); // response interceptor here
return response;
}; fetch('https://jsonplaceholder.typicode.com/todos/1')
.then((response) => response.json())
.then((json) => console.log(json)); // log
// {
// "userId": 1,
// "id": 2,
// "title": "quis ut nam facilis et officia qui",
// "completed": false
// }

这个 API 请求将从 https://jsonplaceholder.typicode.com/todos/2 获取数据,而不是 https://jsonplaceholder.typicode.com/todos/1,并展示 ID 为 2todo 数据。

注意: 请求拦截器最常见的用例之一是更改身份验证的 headers。

响应拦截器

响应拦截器将在 API 响应传递给实际调用者之前拦截它。让我们看看下面的代码:

const { fetch: originalFetch } = window;
window.fetch = async (...args) => {
let [resource, config] = args; let response = await originalFetch(resource, config); // response interceptor
const json = () =>
response
.clone()
.json()
.then((data) => ({ ...data, title: `Intercepted: ${data.title}` })); response.json = json;
return response;
}; fetch('https://jsonplaceholder.typicode.com/todos/1')
.then((response) => response.json())
.then((json) => console.log(json)); // log
// {
// "userId": 1,
// "id": 1,
// "title": "Intercepted: delectus aut autem",
// "completed": false
// }

在上面的代码中,我们更改了 json 方法以返回一些自定义数据来替代原始数据。查看文档了解更多 可以更改的属性

注意: response 只允许使用一次。因此,每次需要使用 response 时,都需要 克隆 response

错误处理

通过检查 response.okresponse.status 的值,可以很容易地处理请求的错误。在下面的代码片段中,可以拦截 404 错误

const { fetch: originalFetch } = window;
window.fetch = async (...args) => {
let [resource, config] = args;
let response = await originalFetch(resource, config);
if (!response.ok && response.status === 404) {
// 404 error handling
return Promise.reject(response);
}
return response;
};
fetch('https://jsonplaceholder.typicode.com/todos/1000000')
.then((response) => response.json())
.then((json) => console.log(json))
.catch((error) => console.error(error));

Node.js

你可以在 Node.js 中使用相同的方法。然而,Node.js 原生不支持 Fetch API (尽管对 Fetch API 的原生支持将在 Node.js 的未来版本中提供)。现在,你需要安装 Node Fetch 包,然后对 fetch 方法使用猴子补丁。【译:Node18已经支持了!】

使用 fetch-intercept 库

如果你不喜欢做这些 dirty 的事情(双关语【译:我也不懂指什么?】) ,那么 fetch-intercept 库允许您使用更干净的 API 注册拦截器。您可以使用 npm 或 Yarn 来安装这个库,如下所示:

npm install fetch-intercept whatwg-fetch --save
// or
yarn install fetch-intercept whatwg-fetch

注意: fetch-intercept 只支持浏览器,不能在 Node.js 中工作。因此,它还需要使用 whatwg-fetch 作为依赖项。

通过下面的代码,我们可以实现与我们的猴子补丁示例相同的请求和响应拦截器:

import * as fetchIntercept from 'fetch-intercept';

const unregister = fetchIntercept.register({
request: function (url, config) {
const modifiedUrl = `https://jsonplaceholder.typicode.com/todos/2`;
return [modifiedUrl, config];
}, requestError: function (error) {
return Promise.reject(error);
}, response: function (response) {
const clonedResponse = response.clone();
const json = () =>
clonedResponse
.json()
.then((data) => ({ ...data, title: `Intercepted: ${data.title}` })); response.json = json;
return response;
}, responseError: function (error) {
return Promise.reject(error);
},
}); fetch('https://jsonplaceholder.typicode.com/todos/1')
.then((response) => response.json())
.then((json) => console.log(json)); // unregister interceptors
unregister();

register 方法允许你为 Fetch API 请求注册拦截器。它接受一个带有 requestrequestErrorresponse, 和 responseError 回调的对象。register 方法返回另一个可用于注销拦截器的方法。

Fetch API 本身不支持拦截器。但是,还有其他支持拦截器的 HTTP 请求库。看一下 Axios,它提供了开箱即用的功能。

总结

在本文中,我们介绍了什么是 JavaScript 拦截器,学习了如何通过给 Fetch API 使用猴子补丁和使用 fetch-intercept 库来创建拦截器。

拦截器最初由 Angular 引入,对于各种各样的用例都很有帮助,比如帮助处理全局错误、身份验证、日志记录等等。你可以使用本文描述的方法将拦截器添加到 JavaScript 应用程序中,但是,请记住在 Node.js 需要添加额外的依赖。

我希望你喜欢这篇文章,如果有任何问题一定要留下评论。Happy coding!

JavaScript 中如何拦截全局 Fetch API 的请求和响应?的更多相关文章

  1. JavaScript中对数组和数组API的认识

    JavaScript中对数组和数组API的认识 一.数组概念: 数组是JavaScript中的一类特殊的对象,用一对中括号“[]”表示,用来在单个的变量中存储多个值.在数组中,每个值都有一个对应的不重 ...

  2. ES6 Fetch API HTTP请求实用指南

    本次将介绍如何使用Fetch API(ES6 +)对REST API的 HTTP请求,还有一些示例提供给大家便于大家理解. 注意:所有示例均在带有箭头功能的 ES6中给出. 当前的Web /移动应用程 ...

  3. Javascript中正则表达式的全局匹配模式

    先看一道JavaScript题目,据说是国内某知名互联网企业的JavaScript笔试题,如果对正则的全局匹配模式不了解的话可能会对下面的输出结果感到疑惑. var str = "123#a ...

  4. 【Azure API 管理】在APIM中使用客户端证书验证API的请求,但是一直提示错误"No client certificate received."

    API 管理 (APIM) 是一种为现有后端服务创建一致且现代化的 API 网关的方法. 问题描述 在设置了APIM客户端证书,用户保护后端API,让请求更安全. 但是,最近发现使用客户端证书的API ...

  5. Dubbo中服务消费者和服务提供者之间的请求和响应过程

    服务提供者初始化完成之后,对外暴露Exporter.服务消费者初始化完成之后,得到的是Proxy代理,方法调用的时候就是调用代理. 服务消费者经过初始化之后,得到的是一个动态代理类,InvokerIn ...

  6. angular 用拦截器统一处理http请求和响应 比如加token

    想使用angularjs里的htpp向后台发送请求,现在有个用户唯一识别的token想要放到headers里面去,也就是{headres:{'token':1}} index.html里引入以下js: ...

  7. fetch API 简单解读

    http://f2e.souche.com/blog/fetch-api-jie-du/?utm_source=tuicool&utm_medium=referral 在我们日常的前端开发中, ...

  8. JavaScript中的XMLHttpRequest与WebAPI

    JavaScript中的XMLHttpRequest与WebAPI它仅仅是一种客户端与服务端的关系.JavaScript中的XMLHttpRequest负责在客户端发起请求,而Web API负责在服务 ...

  9. 详解javascript中的this对象

    详解javascript中的this对象 前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的 ...

  10. Django编写RESTful API(二):请求和响应

    欢迎访问我的个人网站:www.comingnext.cn 前言 在上一篇文章,已经实现了访问指定URL就返回了指定的数据,这也体现了RESTful API的一个理念,每一个URL代表着一个资源.当然我 ...

随机推荐

  1. C++ 使用栈求解中缀、后缀表达式的值

    1. 前言 表达式求值对于有知识积累的你而言,可以通过认知,按运算符的优先级进行先后运算. 但对计算机而言,表达式仅是一串普通的信息而已,需要通过编码的方式告诉计算机运算法则,这个过程中栈起到了至关重 ...

  2. Java学习之路:运算符

    2022-10-10 10:34:08 1 运算符 算术运算符:+, -, *, /, %, ++, -- 赋值运算符:= 关系运算符:>, <, >=, <=, ==, != ...

  3. .NET Core C#系列之XiaoFeng.Threading.JobScheduler作业调度

    作业调度其实就是一个定时器,定时完成某件事, 比如:每分钟执行一次,每小时执行一次,每天执行一次,第二周几执行,每月几号几点执行,间隔多少个小时执行一次等. 作业类:XiaoFeng.Threadin ...

  4. Windows Server 2012部署遇到的问题

    一.安装IIS提示"服务器管理器WinRM插件可能已损坏或丢失" 解决方案: 1.开启WinRM服务,添加ip监听 在服务中查看WinRM服务是否开启,如果没有开启则把该服务开启, ...

  5. etcd实现分布式锁

    转载自:etcd实现分布式锁 当并发的访问共享资源的时候,如果没有加锁的话,无法保证共享资源安全性和正确性.这个时候就需要用到锁 1.需要具备的特性 需要保证互斥访问(分布式环境需要保证不同节点.不同 ...

  6. SpringBoot内置工具类,告别瞎写工具类了

    不知大家有没有注意到,接手的项目中存在多个重复的工具类,发现其中很多功能,Spring 自带的都有.于是整理了本文,希望能够帮助到大家! 一.断言 断言是一个逻辑判断,用于检查不应该发生的情况 Ass ...

  7. css文字单行/多行超出显示省略号...

    css文字单行/多行超出显示省略号... 项目里写css样式我们经常会遇到将文字超出显示省略号的情况,记录一下以后能用到. 单行超出 .oneline { width:300upx; /*宽度一定要设 ...

  8. 题解 CF327A Flipping Game

    前言 数据水的一批,\(\mathcal{O}(n^3)\) 给过我觉得是不应该的. 题意 有一个由 \(0\) 和 \(1\) 组成的序列 \(a_1,a_2,a_3,a_4....,a_n\) . ...

  9. Programiranje 方法记录

    [COCI2017-2018#3] Programiranje 题面翻译 题目描述 Little Leticija正在准备编程考试.虽然她已经解决了很多任务,但还有一个任务尚未解决,所以她正在向你寻求 ...

  10. Xtrabackup使用帮助

    目录 1.安装工具 2.下载后上传到需要备份的服务器 全备 1.安装完成后我们进行数据库备份执行以下命令 2.查看备份的数据 3.进入数据库,删除一个测试库 4.删除school库 5.备份数据目录 ...