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 ...
随机推荐
- PHP 正则表达式的简单应用以 preg_match_all 抓取HTML元素为例 [转载]
PHP 正则表达式的简单应用以 preg_match_all 抓取HTML元素为例 2011-12-02 17:09:39| 分类: PHP|举报|字号 订阅 下载LOFTER我的照片书 ...
- CSS技巧 (1) · 结构和布局
前言 这一篇主要是总结关于结构和布局的一些技巧,不管什么,一个网页上来,最重要的是先确定他的结构和布局,实现基本的布局之后,我们再进行局部的优化和交互特效. 这一篇主要讲 关于 自适应内部元素 的内 ...
- 检测MySQL主从是否异常
#!bin/bash user='root' passwd="123" host="192.168.192.156" mycmd="mysql -u$ ...
- 报错fatal: refusing to merge unrelated histories
提交到远程仓库的时候报错如下 是因为远程仓库有东西更新,但本地仓库没有更新造成提交失败 需要先把远程仓库给拉取下来,执行命令git pull origin master,又报错了如下 是因为两个仓库提 ...
- CSS隐藏元素 display、visibility、opacity的区别
关于使指定元素无法在视野内看到,有3个方法 display: none; opacity: 0; visibility: hidden; 1.display: none; 该方法会改变页面布局. 元素 ...
- 零基础转行web前端,要学习多久?需要掌握些什么?
web前端开发技术人才越来越吃香,而且web前端领域划分越来越细,对技术的需求越来越高,想学习web前端的人也是越来越多.那么,如何学习web前端知识?从哪开始?转型成为web前端工程师需要学些什么? ...
- PHP each
1.函数的作用:遍历数组元素 2.函数参数: @params array &$array 3.例子: <?php $arr = ['Boy','Girl']; while(list($k ...
- Python斐波那契数列
今天偶然看到这个题目,闲着没事练一下手 if __name__ == '__main__': """ 斐波那契数列(Fibonacci sequence), 又称黄金分割 ...
- (转载)linux命令-sed
原文地址:https://www.cnblogs.com/zhangzongjian/p/10708222.html
- python-url中中文编码与解码
接口测试中遇到这种情况:get请求的传参有中文,以致url中有中文编码. 下面是常见的一种编码解码方式: from urllib.request import quote, unquote url = ...