SignalR 跨域问题(Vue3+Net6)

文章目录

  • 背景
  • 困难
      • ~~*调用 UseCors*~~
  • 解决办法
    • 环境
    • 错误信息
    • 解决方式
      • 部分代码
  • 问题分析

背景

使用前后端分离技术,前端使用Vue,部署在独立的服务器上,后端接口部署在另外一个服务器上。

困难

网上找了一个多小时的SignalR的跨域问题,包括微软官网的一些说明都是这样的(下面这段在.net6中不好用)

https://learn.microsoft.com/zh-cn/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client#crossdomain

调用 UseCors

以下代码片段演示如何在 SignalR 2 中实现跨域连接。

在 SignalR 2 中实现跨域请求

以下代码演示如何在 SignalR 2 项目中启用 CORS 或 JSONP。 此代码示例使用 MapRunSignalR 而不是 MapSignalR,以便 CORS 中间件仅针对需要 CORS 支持 (的 SignalR 请求运行,而不是针对 .) Map 中指定的 MapSignalR路径上的所有流量运行,也可用于需要针对特定 URL 前缀运行的任何其他中间件,而不是针对整个应用程序运行。

**

using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Owin;
namespace MyWebApplication
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Branch the pipeline here for requests that start with "/signalr"
            app.Map("/signalr", map =>
            {
                // Setup the CORS middleware to run before SignalR.
                // By default this will allow all origins. You can 
                // configure the set of origins and/or http verbs by
                // providing a cors options with a different policy.
                map.UseCors(CorsOptions.AllowAll);
                var hubConfiguration = new HubConfiguration 
                {
                    // You can enable JSONP by uncommenting line below.
                    // JSONP requests are insecure but some older browsers (and some
                    // versions of IE) require JSONP to work cross domain
                    // EnableJSONP = true
                };
                // Run the SignalR pipeline. We're not using MapSignalR
                // since this branch already runs under the "/signalr"
                // path.
                map.RunSignalR(hubConfiguration);
            });
        }
    }
}

备注

  • 不要在代码中将 设置为 jQuery.support.cors true。

    不要将 jQuery.support.cors 设置为 true

    SignalR 处理 CORS 的使用。 将 设置为 jQuery.support.cors true 会禁用 JSONP,因为它会导致 SignalR 假定浏览器支持 CORS。

  • 连接到 localhost URL 时,Internet Explorer 10 不会将其视为跨域连接,因此即使尚未在服务器上启用跨域连接,应用程序也会在本地使用 IE 10。

  • 有关将跨域连接与 Internet Explorer 9 配合使用的信息,请参阅 此 StackOverflow 线程。

  • 有关将跨域连接与 Chrome 配合使用的信息,请参阅 此 StackOverflow 线程。

  • 示例代码使用默认的“/signalr”URL 连接到 SignalR 服务。 有关如何指定其他基 URL 的信息,请参阅 ASP.NET SignalR 中心 API 指南 - 服务器 - /signalr URL。

解决办法

环境

  • .net6
  • webapi
  • vue3

错误信息

Access to fetch at ‘https://localhost:6001/sr/warning_broadcast/negotiate?negotiateVersion=1’ from origin ‘http://localhost:8080’ 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. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

解决方式

添加跨域支持

   app.UseCors(opt =>
            {
                
 //不要允许所有源,因为这样编译会报错
                opt.WithOrigins("http://localhost:8080").AllowAnyHeader().AllowAnyMethod().AllowCredentials();
            });

部分代码


            var app = builder.Build();

            // Configure the HTTP request pipeline.
            //if (app.Environment.IsDevelopment())
            //{
            app.UseSwagger();
            app.UseSwaggerUI();
            //}

            app.UseStaticFiles(); 

            app.UseHttpsRedirection();

            app.UseAuthorization();
             
            app.MapControllers();

            app.UseCors(opt =>
            {
                opt.WithOrigins("http://localhost:8080").AllowAnyHeader().AllowAnyMethod().AllowCredentials();
            });
            #region SignalR
            app.MapHub("/sr/warning_broadcast");  
            #endregion 

            app.Run();

问题分析

  • 通过观察客户端的错误信息发现是一个post请求出现了跨域问题,所以可以确定问题的本质不是signalR的跨域问题,而是webapi的跨域问题。
  • 在配置跨域的时候需要注意,同一个域名下的不同端口也属于跨域,所以配置跨域源的时候要增加端口
  • 因为SignalR在连接前的post请求都是包含验证信息的,所以要支持AllowCredentials()

你可能感兴趣的:(.netcore,c#,websocket,vue.js)