作为一个上进的程序猿必须要紧跟技术。等core出来稳定后(企业招聘基本全要会core,不会混不了饭吃泪)决定要掌握core。于是在腾讯课堂花了1.1软妹币白嫖了2门课程后又在B站学习一门掌握了入门知识即可进入自学时代了。
好现在开始把学生时做的后来用其它技术改版2遍仿QQ即时聊天工具迁移到core3.1+signalr+grpc,也就是单个web有多个页面+多个web(独立网站独立部署)+桌面程序+手机APP互通聊天
不过做到第一个signalr跨域的时候就遇到了不小阻力。所以这篇就是把signalr跨域单独拿出来做一篇,(不是上面的IM开发遇到的问题的案例是遇到问题单独抽出来做个DEMO,反正也刚开始改版问题目前只遇到signalr跨域)IM的话等积累到一个阶段再发
正戏开始伟大的分割线
我的项目结构:上面是提供资源访问的signalr服务端端口5001,下面端口5000因为方便就把做grpc+signalr的DEMO拿过来了。
遇到的问题:
因为当时问题很多反复调了近3天都不得,但是当时心如死灰没心情截图bug下来。所以只好凭着程序猿自带的渣记忆还原几个问题
问题1:
localhost/:1 Access to XMLHttpRequest at 'https://localhost:5001/ChatMsgCorsHub/negotiate' from origin 'https://localhost:5000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
网上百度:找到https://blog.csdn.net/a914541185/article/details/83181919
很可惜不行
问题2:
Access to XMLHttpRequest at 'https://localhost:5001/ChatMsgCorsHub/negotiate' from origin 'https://localhost:5000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
解决:
写个中间件增加回复头
public class CorsServerMiddleware
{
private readonly RequestDelegate _next;
public CorsServerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (!context.Response.Headers.ContainsKey("Access-Control-Allow-Origin"))
{
context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
context.Response.Headers.Add("Access-Control-Allow-Methods", "*");
context.Response.Headers.Add("Access-Control-Max-Age", "3600");
context.Response.Headers.Add("Access-Control-Allow-Headers", "x-requested-with,Authorization");
context.Response.Headers.Add("Access-Control-Allow-Credentials", "false");
}
await _next(context);
}
}
OK.出现问题3:
Access to XMLHttpRequest at 'https://localhost:5001/ChatMsgCorsHub/negotiate' from origin 'https://localhost:5000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
这个问题很鬼畜。。。我就是调了近一天都无果。。。还出现别的很多问题,但是没记下来BUG。所以直接到最后一步方案:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
//登录用户使用
options.AddPolicy("any", builder =>
{
builder.WithOrigins(
"http://crm.muzixiaohua.com/",
"http://localhost:64151",
"http://localhost:8080",
"null")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
//公开使用
options.AddPolicy("all", builder =>
{
builder.WithOrigins("*")
.AllowAnyMethod()
.AllowAnyHeader();
});
});
services.AddControllersWithViews();
services.AddSignalR();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMiddleware();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseCors("CorsPolicy"); //之前这句写到 下面去了导致一直报跨域访问的错误,顺序必须在 app.UseSignalR ... 这句设置之前才行,
app.UseRouting();
//注册signalr--指定跨域方案
app.UseCors("any")
.UseEndpoints(endpoints =>
{
endpoints.MapHub(pattern: "/ChatMsgCorsHub");
});
}
问题4:
Access to XMLHttpRequest at 'https://localhost:5001/ChatMsgCorsHub/negotiate' from origin 'https://localhost:5000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
解决方案:
options.AddPolicy("any", builder =>
{
builder.WithOrigins(
"http://crm.muzixiaohua.com/",
"http://localhost:64151",
"http://localhost:8080",
"https://localhost:5001",//增加
"https://localhost:5000",//增加
"null")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
还是不行:。。。出现上面的问题1。。。哈?百度N久改了一(亿)遍,仍然不行
这时候心累。。。万念俱灰觉得这个不是自己能力能解决的。。
收工玩大蛇无双3,正好我xbox手柄不能连发,自己找API开发一个连发软件。。。就这么过了一天。。
今天一脸死灰的打开这个DEMO...回忆一下上次的问题。。运行上面再运行下面。。
这个是 火山爆发.gif
可以了。没问题了。能正常运行了。什么鬼?
点击跨域按钮
全部没问题,代码就和上面写的最后一个一样。啥没改。
我知道。。了。。这就是
附带说一句:
把上面的:中间件增加回复头 去掉依然没问题。。能正常运行
今天人品爆发。。见好就收。。