Net Core中 使用Middleware 实现反向代理
有这样的一个需求,我们要拦截某些特定的请求,并将它们重新定向到另一台服务器中,然而客户端并不知情。
在NetCore中我们可以用中间件来实现,
为什么要使用反向代理
反向代理一般在下面的场景中进行使用:
负载均衡:
反向代理。它可以根据一些特定算法在一组相同的服务器之间分配请求负载,从而为系统的可伸缩性和可用性提供支持。
网址重写:
可以将无法更改的网络路径隐藏在反向代理后面。
静态内容投放:
反向代理服务器可以充当Web服务器。这使您可以将它们用于提供静态内容,例如HTML页面,JavaScript脚本,图像和其他文件,同时将对动态内容的请求转发到专用服务器。这是一种基于内容类型的负载平衡。
API网关:
在具有微服务架构的系统中,您有多个服务器通过其API提供不同的服务。您可以使用反向代理来公开服务器API组合的单个入口点。
多个网站合并:
使多个网站使用共同的一个入口(网站),和微服务中的网关作用差不多。
首先创建项目:
我这里只有2.1 Version 的

添加ProxyMiddleware

ProxyMiddleware内容如下:
代码不多有兴趣的朋友可以调试一下。这里还可以有很多的方向扩展。
public class ProxyMiddleware
{
private static readonly HttpClient _httpClient = new HttpClient();
private readonly RequestDelegate _nextRequestDelegate;
private static readonly Uri _targetUri = new Uri("https://www.cnblogs.com/");
public ProxyMiddleware(RequestDelegate nextMiddleware)
{
_nextRequestDelegate = nextMiddleware;
}
public async Task Invoke(HttpContext context)
{
bool validateUri = false;
if (context.Request.Path.StartsWithSegments("/api/values", out var Path))
{
validateUri = true;
}
if (validateUri == true)
{
var targetRequestMessage = CreateTargetMessage(context);
using (var responseMessage = await _httpClient.SendAsync(targetRequestMessage))
{
context.Response.StatusCode = (int)responseMessage.StatusCode;
CloneResponseHeadersIntoContext(context, responseMessage);
await responseMessage.Content.CopyToAsync(context.Response.Body);
}
return;
}
await _nextRequestDelegate(context);
}
private void CloneRequestContentAndHeaders(HttpContext context, HttpRequestMessage requestMessage)
{
foreach (var header in context.Request.Headers)
{
requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
}
}
private HttpRequestMessage CreateTargetMessage(HttpContext context)
{
var requestMessage = new HttpRequestMessage();
CloneRequestContentAndHeaders(context, requestMessage);
requestMessage.RequestUri = _targetUri;
requestMessage.Headers.Host = _targetUri.Host;
requestMessage.Method = new HttpMethod(context.Request.Method);
return requestMessage;
}
private void CloneResponseHeadersIntoContext(HttpContext context, HttpResponseMessage responseMessage)
{
foreach (var header in responseMessage.Headers)
{
context.Response.Headers[header.Key] = header.Value.ToArray();
}
foreach (var header in responseMessage.Content.Headers)
{
context.Response.Headers[header.Key] = header.Value.ToArray();
}
context.Response.Headers.Remove("Transfer-Encoding");
}
}
添加管道
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMiddleware<ProxyMiddleware>();
app.UseMvc();
}
运行结果:
大家可以注意浏览器网址,以及显示的内容就可以了,(样式没了)

代码解释:
所有的描述在代码中,这里我只是标出这点代码的重点
创建静态HttpClient连接,减少连接池数量
private static readonly HttpClient _httpClient = new HttpClient();
private readonly RequestDelegate _nextRequestDelegate;
新的目标服务器
private static readonly Uri _targetUri = new Uri("https://www.cnblogs.com/");
public ProxyMiddleware(RequestDelegate nextMiddleware)
{
_nextRequestDelegate = nextMiddleware;
}
所有的工作将由 Invoke执行
public async Task Invoke(HttpContext context)
{
bool validateUri = false;
if (context.Request.Path.StartsWithSegments("/api/values", out var Path))
{
validateUri = true;
}
if (validateUri == true)
{
var targetRequestMessage = CreateTargetMessage(context);
using (var responseMessage = await _httpClient.SendAsync(targetRequestMessage))
{
context.Response.StatusCode = (int)responseMessage.StatusCode;
CloneResponseHeadersIntoContext(context, responseMessage);
await responseMessage.Content.CopyToAsync(context.Response.Body);
}
return;
}
await _nextRequestDelegate(context);
}
private void CloneResponseHeadersIntoContext(HttpContext context, HttpResponseMessage responseMessage)
{
foreach (var header in responseMessage.Headers)
{
context.Response.Headers[header.Key] = header.Value.ToArray();
}
foreach (var header in responseMessage.Content.Headers)
{
context.Response.Headers[header.Key] = header.Value.ToArray();
}
这里有一个坑大家注意了,有兴趣的同学可以调查研究一下,要是介绍的话可以单独开一篇了
context.Response.Headers.Remove("Transfer-Encoding");
}
有不足之处 希望大家指出相互学习。
Net Core中 使用Middleware 实现反向代理的更多相关文章
- [C#]使用 C# 代码实现拓扑排序 dotNet Core WEB程序使用 Nginx反向代理 C#里面获得应用程序的当前路径 关于Nginx设置端口号,在Asp.net 获取不到的,解决办法 .Net程序员 初学Ubuntu ,配置Nignix 夜深了,写了个JQuery的省市区三级级联效果
[C#]使用 C# 代码实现拓扑排序 目录 0.参考资料 1.介绍 2.原理 3.实现 4.深度优先搜索实现 回到顶部 0.参考资料 尊重他人的劳动成果,贴上参考的资料地址,本文仅作学习记录之用. ...
- dotNet Core WEB程序使用 Nginx反向代理
之前记录过一篇 使用 jexus 作为dotNetCore的反向代理,发现jexus的内存占用较大,最终选择使用Nginx的原因就是占用内存较小,以及性能较优(https://www.cnblogs. ...
- IIS中利用ARR实现反向代理
反向代理是什么,不了解的,请自行百度.本人也是最近才研究这个主题,简单的来说,利用这项技术可以实现负载均衡,安全控制等web应用中重要的功能,对于web应用来说这是个很基础,也很重要的技术,值得开发者 ...
- Linux系统中使用Nignx配置反向代理负载均衡
目录 使用nginx实现动静分离的负载均衡集群 使用nginx实现负载均衡和动静分离 使用nginx实现动静分离的负载均衡集群 Nginx官网源码包下载链接:http://nginx.org/en/d ...
- Linux中配置端口转发(反向代理)
在conf.d目录下建一个文件, 以conf为结尾(如果没有conf.d目录,就自己新建一个) server { listen 80; server_name 127.0.0.1; #这个IP是你服务 ...
- react项目中怎么使用http-proxy-middleware反向代理跨域
第一步 安装 http-proxy-middleware npm install http-proxy-middleware 我们这里面请求用的axios,在将axios安装一下 npm instal ...
- .Net Core实践4 web 反向代理
目标 将控制台程序改成web程序,通过IIS反向代理,处理请求 环境 win10 / .net core 2.1 / centos7 变成web程序 1.在新建的asp.net core控制台程序中添 ...
- Centos8 Docker+Nginx部署Asp.Net Core Nginx正向代理与反向代理 负载均衡实现无状态更新
首先了解Nginx 相关介绍(正向代理和反向代理区别) 所谓代理就是一个代表.一个渠道: 此时就涉及到两个角色,一个是被代理角色,一个是目标角色,被代理角色通过这个代理访问目标角色完成一些任务的过程称 ...
- 如何设计出和 ASP.NET Core 中 Middleware 一样的 API 方法?
由于笔者时间有限,无法写更多的说明文本,且主要是自己用来记录学习点滴,请谅解,下面直接贴代码了(代码中有一些说明): 01-不好的设计 代码: using System; namespace Desi ...
随机推荐
- office2019激活
这个是在网上偶然看见的一个激活方式,分享一下. 复制如下代码保存后修改文件后缀名为".bat",请注意有一个点,然后保存以管理员身份运行即可: @echo off(cd /d &q ...
- yii2 验证规则使用方法
required : 必须值验证属性 [['字段名'],required,'requiredValue'=>'必填值','message'=>'提示信息']; #说明:CRequiredV ...
- Javascript中Promise的简单使用
// 函数功能:1秒以后创建一个10以内的随机整数,并判断这个数是否为偶数:如果是偶数则做一件事情,如果是奇数则做另一件事情 function doSomthing() { var promise = ...
- ActiveMQ学习总结------实战操作(上)02
相信大家通过上一篇博文已经对ActiveMQ有了一个大致的概念了, 那么本篇博文将带领大家一步一步去实战操作我们的ActiveMQ 本篇主要内容: 1.ActiveMQ术语及API介绍 2.Activ ...
- 强大得分布式项目管理工具Git
---恢复内容开始--- 强大的分布式管理工具-Git(一) 前言:最近忙着写项目,在期间呢,用的是git管理,由于一个项目的管理是很重要得,所以整理了一篇关于git得博客跟大家分享一下.大家都知道, ...
- 服务器时间误差导致的google sign-in后台验证错误(远程调试java程序)
https://developers.google.com/identity/sign-in/web/backend-auth import com.google.api.client.googlea ...
- Web高性能动画及渲染原理(1)CSS动画和JS动画
目录 一. CSS动画 和 JS动画 1.1 CSS动画 1.2 JS动画 1.3 小结 二. 使用Velocity.js实现动画 示例代码托管在:http://www.github.com/dash ...
- python编程基础之十一
循环语句:周而复始,在满足某个条件下,重复做相同或类型的事情, 循环语句三要素:循环条件 + 循环体 + 循环条件改变while 条件 : 循环体 循环条件改变... while 条件 : 循环体 循 ...
- TCP方式的传输
TCP 客户端 先创建socket对象建立tcp客户端,明确服务端的地址和端口,必须与服务端对应,要不然对方收不到消息,就像快递填错了送货地址. Socket s = new Socket(" ...
- java架构之路-(Redis专题)Redis的高性能和持久化
上次我们简单的说了一下我们的redis的安装和使用,这次我们来说说redis为什么那么快和持久化数据 在我们现有的redis中(5.0.*之前的版本),Redis都是单线程的,那么单线程的Redis为 ...