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 ...
随机推荐
- 安装/删除MySQL数据库
MySQL的数据存储目录为data,data目录通常在C:\Documents and Settings\All Users\Application Data\MySQL\MySQL Server 5 ...
- pyinstaller 打包exe程序读不到配置文件No such file
挺久没更新博客的,一来之前是觉得才疏学浅,记录下来的太简单没人看.二来时间上不是很充裕(不是借口,有时间打游戏,没时间总结) 偶然有一次发现同事在搜索解决问题的时候正在看我博客的解决思路,很奇妙的感觉 ...
- MySql5.5安装步骤及MySql_Front视图配置
一.下载文件 有需要的朋友,请自行到百度云下载 链接:https://pan.baidu.com/s/13Cf1VohMz_a0czBI05UqJg 提取码:cmyq 二.安装MySql 2.1.运行 ...
- MongoDB 学习笔记之 索引
索引: db.media.createIndex({"Tracklist": 1}) 1表示升序 -1表示降序 我们要着重看一下对数组创建索引的情况. 构建一个集合:db.medi ...
- [docker swarm] 从单容器走向负载均衡部署
背景 之前写过<<docker-compose真香>> 和<docker-compose.docker stack前世今生>两篇博客, 回顾一下思路: ① dock ...
- SpringBootSecurity学习(22)前后端分离版之OAuth2.0自定义授权码
使用JDBC维护授权码 前面的代码中,测试流程第一步都是获取授权码,然后再携带授权码去申请令牌,授权码示例如下: 产生的授权码默认是 6 位的,产生以后并没有做任何管理,可以说是一个临时性的授权码,o ...
- drf框架中认证与权限工作原理及设置
0909自我总结 drf框架中认证与权限工作原理及设置 一.概述 1.认证 工作原理 返回None => 游客 返回user,auth => 登录用户 抛出异常 => 非法用户 前台 ...
- Spring Security 入门(一)
当你看到这篇文章时,我猜你肯定是碰到令人苦恼的问题了,我希望本文能让你有所收获. 本人几个月前还是 Spring 小白,几个月走来,看了 Spring,Spring boot,到这次的 Spring ...
- 如何用js做关灯游戏
编辑器 Sublime Text 3 <!DOCTYPE html><html lang="en"><head> <meta chars ...
- 防止CSRF跨站请求伪造
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站 ...