http-proxy-middleware
1、定义:
是一个代理中间件,用于转发请求,将客户端发送的请求数据转发到目标服务器,再将响应输送到客户端。
2、核心概念
如何配置一个代理中间件
1、createProxyMiddleware([context,] config)
- context:匹配请求的路径
- options:中间件配置
2、option
- 属性
- 代理事件
1、常用属性:
- target :用于设定目标服务器的 host
- router: 根据客户端请求重新设定目标服务器的 host(这样,根据不同的请求,可以设定多个目标服务器)
- pathRewrite:将客户端请求路径转化为目标服务器地址。
- changeOrigin:是否将主机标头的来源更改为目标URL
- **secure:**是否验证SSL证书
2、监听代理事件
1、error
:发出错误事件。框架不对客户端和代理之间传递的消息以及代理和目标之间传递的消息进行任何错误处理,需要手动监听错误并进行处理。
2、proxyReq
:在发送数据之前发出此事件。它使您有机会更改proxyReq请求对象。
3、proxyReqWs
:在发送数据之前发出此事件。它使您有机会更改proxyReq请求对象。适用于“ websocket”连接
4、proxyRes
:如果对目标的请求得到响应,则发出此事件。
5、open
:创建代理Websocket并将其通过管道传输到目标Websocket后,将发出此事件。
6、close
:关闭代理websocket后,将发出此事件。
(proxySocket
不推荐使用):不推荐使用open
。
3、应用一个代理中间件的步骤
1、创建并配置一个代理中间件
2、在项目中注册中间件
1、应用举例:
目的:
proxyRes:这里将目标主机返回的response data包装成
{code:200data:proxyRes.data
}
写进res对象,返回给client
代码:
import {NestFactory} from '@nestjs/core';
import {AppModule} from './app.module';
import {createProxyMiddleware} from "http-proxy-middleware";
import {IncomingMessage} from "http";async function sleep(interval) {return new Promise(resolve => {setTimeout(resolve, interval);})
}async function bootstrap() {const app = await NestFactory.create(AppModule);app.use("/api",createProxyMiddleware({target: 'http://localhost:3001',changeOrigin:true,pathRewrite: {'/api/hello': '/hello'},secure: false,selfHandleResponse: true,onProxyReq: (proxyReq, req, res) => {if (req.body) {const bodyData = JSON.stringify(req.body)// incase if content-type is application/x-www-form-urlencoded -> we need to change to application/jsonproxyReq.setHeader("Content-Type", "application/json")proxyReq.setHeader("Content-Length", Buffer.byteLength(bodyData))// stream the contentproxyReq.write(bodyData)}// 禁用缓存// proxyReq.setHeader('Cache-Control', 'no-cache');// res.send("req")//// console.log(res.getHeaders())},onProxyRes: async (proxyRes, req, res) => {let bodyResbodyRes = await getBody(proxyRes)console.log("1 res from proxied server:", bodyRes);res.json({code: 200,data: bodyRes,})},onError: (err, req, res) => {res.writeHead(500, {'Content-Type': 'text/plain',});res.end('Something went wrong. And we are reporting a custom error message.');}}));await app.listen(3002);
}function getBody(proxyRes: IncomingMessage) {return new Promise((resolve, reject) => {let body = []proxyRes.on('data', function (chunk) {body.push(chunk)})let bodyStr = ""proxyRes.on('end', function () {bodyStr = Buffer.concat(body).toString()console.log('getBody ======', bodyStr)resolve(bodyStr)})})
}bootstrap();
2、注意:
1、如果要给客户端手动返回响应值,
在这里要注意,我们需要设置
因为:
1、如果设置了selfHandleResponse=true的话,代理服务器会发射一个“end“事件,当客户端响应对象res监听到这个事件后,可以自己修改响应
2、如果不设置selfHandleResponse=true的话,代理响应对象proxyRes会将响应流直接pipe(写)进客户端res响应对象,直接响应到客户端
当我们想要修改响应时
会报如下错误
提示我们,不能在响应发送给客户端之后再来修改响应头,因为不设置selfHandleResponse=true,代理响应对象proxyRes会将响应流直接pipe(写)进客户端res响应对象,直接响应到客户端
2、如果在proxyReq阶段,直接返回res
客户端会立即收到响应,
在req.send之后,也可以在onProxyReq中打印出响应对象
如果有多个中间件,只会执行完当前的代理中间件,然后直接响应客户端,后面的中间件不会再执行
不会立即中断当前中间件,后面的代理过程还是会执行(应用场景:客户端删除十万条商品信息,可以立即返回客户端“正在删除中,请稍等”,然后代理去执行删除),拿到代理对象的返回并打印返回值“hello world"
res.json({code: 200,data: bodyRes,})
但是当执行res.json给客户端发送响应时报错,不能在响应已经发送给client后再次设置信息(因为proxyReq已经给客户端响应)
4、实现原理
1、获取中间注册的配置信息,生成一个代理服务器
2、根据 options.pathRewrite 生成路径转化器 pathRewriter
3、为代理服务器绑定监听事件
4、创建转发 http, https, websocket 请求的代理中间件。
中间件,请求阶段为什么可以拿到res对象
express源码:
1、创建application
创建app时会创建req和res对象
request对象提供create方法根据底层的http对象来创建一个request对象
reaponse对象提供create方法根据底层的http对象来创建一个response对象
创建一个中间件时,会将app中创建的request和response对象注册进来
5、总结
1、http-proxy-middleware 是一个代理中间件,用于转发请求到目标服务器
2、可以监听代理对象的请求和响应,以增强请求和响应
3、实现原理:本质上是一个中间件,添加了代理对象的监听事件,以至于我们能够灵活处理代理对象
http-proxy-middleware相关推荐
- 使用 SAP Fiori Tools 部署 SAP UI5 应用到 ABAP 服务器时遇到的各种错误和解决办法
错误1 (node:28340) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'customMiddleware ...
- Node.js Web 开发框架大全《中间件篇》
这篇文章与大家分享优秀的 Node.js 中间件模块.Node 是一个服务器端 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用程序,编写能够处 ...
- Caddy,一个用Go实现的Web Server | 比Apache速度快,比Nginx有个性
Caddy,一个用Go实现的Web Server | 比Apache速度快,比Nginx有个性 作者介绍 Tony Bai:C程序员,供职于国内某大型软件公司.喜技术,爱钻研:热爱开源,曾先后贡献了l ...
- 爬虫、网页测试 及 java servlet 测试框架等介绍
scrapy 抓取网页并存入 mongodb的完整示例: https://github.com/rmax/scrapy-redis https://github.com/geekan/scrapy-e ...
- 2021第三届长安杯
检材一 2021年4月25日,上午8点左右,警方接到被害人金某报案,声称自己被敲诈数万元.经询问,昨日金某被嫌疑人诱导裸聊,下载了某"裸聊"软件,导致自己的通讯录和裸聊视频被嫌疑人 ...
- 爬虫基本原理与实战---1、爬虫实战概述
一.开发前准备 1.开发环境准备 基础准备(win10) 参考:python2与python3共存安装 参考: pycharm安装及永久激活 参考: mysql及navicat安装与使用及navica ...
- 前端工程化之动态数据代理
引言 在前端开发过程中,开发者通常都会遇到前端数据不能正常获取的问题,这就需要开发者之间'想办法'搞到这些数据:开发过程中我们可能遇到的场景: 后端接口数据开发中暂时不可用,需要前端在自己本地mock ...
- vue dev环境API代理实现
基本描述 如果你的前端应用和后端 API 服务器没有运行在同一个主机上,你需要在开发环境下将 API 请求代理到 API 服务器.这时候我们就需要使用API代理了. 代码实现 devServer.pr ...
- 年度文章集合 | 最全微前端集合【建议收藏】
欢迎小伙伴们推荐微前端优秀的学习资源 -- awesome-micro-frontends 微前端是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个 ...
- 色字当头一把刀,看我如何用Python针对裸聊渗透测试
本篇文章由知柯™️信息安全&CSDN博主鸿渐之翼联合发布,转载请标明出处! 深圳市狩猎者网络安全技术有限公司旗下安全团队 CSDN:@知柯信息安全 知柯信息安全,用心呵护您的安全!Profes ...
最新文章
- Windows Embedded Standard开发初体验(四)
- httppost数据上传 unity_Unity中国增强版发布
- 关于HTTPS的七个误解
- 2019-03-22-算法-进化(回文链表)
- kotlin-unresolved reference daclaredFunctions
- P1040 加分二叉树【dp+深搜】
- python语法参数_python默认参数语法
- ADO 连接数据库的几种方式
- mysql 6.0 新特性 2014_MySQL 各版本的特性
- Die notwendige Evolution menschlichen Verhalten
- Python之socketserver源码分析
- 互联网之达芬奇密码:浪潮揭秘:与中国五亿网民互为影响的互联网DNA
- Mac安装wget的两种方法
- js Array 标准方法
- Python之条件竞争
- 推荐:常用的代码编辑器!
- 我是个女生,只有这样我才能找到工作
- 帆软:根据参数查看不同报表
- 数据结构学习,哈希表(链地址)
- MATLAB2018a 64安装
热门文章
- 互联网晚报 | 5月19日 星期四 | 腾讯起诉vivo不正当竞争;市监局将立案调查妇炎洁问题广告;天津高考调整至6月12日举行...
- PowerDesigner Excel导入信息
- IDEA打包时clean报错Failed to delete
- MATLAB plot绘图颜色及配色
- QTableWidget中如何清空行,并保持行仍可再写入数据
- Android:Handler中的Idle Handler
- 【IPC通信】key_t键和ftok函数
- SSH(Struts,Spring,Hibernate )和SSM(SpringMVC,Spring,MyBatis )的区别,抽丝剥茧的给你讲清楚
- 什么是分布式?分布式与集群的区别是什么?
- 田野调查手记·浮山篇(一)