原生JS客户端对接.NET Core服务端跨域SignalR的导入报错问题
原生JavaScript对接.NET Core跨域SignalR解决方案
原生JavaScript完全可以对接跨域的SignalR,你遇到的问题集中在客户端引入方式错误和服务端跨域配置不符合SignalR要求两个方面,按以下步骤修正即可:
一、修正SignalR客户端引入方式
你遇到的所有导入报错,本质是因为原生ES模块不支持npm裸包名导入,且你选错了SignalR客户端文件格式:
推荐方案:UMD格式直接引入(纯静态页无需处理import)
直接从npm包@microsoft/signalr/dist/browser/signalr.js路径下复制文件到你的项目静态目录,在HTML中用script标签全局引入:
<script src="./signalr.js"></script>
引入后全局会自动挂载signalR对象,不需要额外写import语句。
可选方案:ES模块导入
如果必须使用ES模块的import写法,需要复制@microsoft/signalr/dist/esm/signalr.js到项目目录,按以下方式导入:
import * as signalR from './signalr.js'
注意:HubConnectionBuilder是构造函数,调用时必须加new关键字,你之前的代码漏掉了new才会报"不是构造函数"的错误。
二、修正服务端.NET Core跨域配置
SignalR的跨域要求比普通接口严格,必须按以下规则配置:
- 注册跨域服务时必须允许凭证,且不能使用通配符
*作为允许的源,要填写前端实际访问地址:
builder.Services.AddCors(options => { options.AddPolicy("SignalRCorsPolicy", policy => { policy.WithOrigins("http://10.50.28.251:8080") // 替换为你的前端实际地址 .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); // 必须配置,SignalR依赖凭证传输 }); });
- 中间件顺序必须正确,且给Hub单独绑定跨域策略:
app.UseRouting(); app.UseCors("SignalRCorsPolicy"); // 必须放在UseRouting之后、UseAuthorization之前 app.UseAuthorization(); app.MapHub<ChatHub>("/chatHub").RequireCors("SignalRCorsPolicy");
三、修正后前端完整代码
删除所有import语句,直接使用全局挂载的signalR对象即可:
// 所有import语句全部删除 // 构造函数前加new关键字 var connection = new signalR.HubConnectionBuilder().withUrl("https://localhost:44368/chatHub").build(); //Disable send button until connection is established document.getElementById("sendButton").disabled = true; connection.on("ReceiveMessage", function (user, message) { var li = document.createElement("li"); document.getElementById("messagesList").appendChild(li); li.textContent = `${user} says ${message}`; }); connection.start().then(function () { document.getElementById("sendButton").disabled = false; }).catch(function (err) { return console.error(err.toString()); }); document.getElementById("sendButton").addEventListener("click", function (event) { var user = document.getElementById("userInput").value; var message = document.getElementById("messageInput").value; connection.invoke("SendMessage", user, message).catch(function (err) { return console.error(err.toString()); }); event.preventDefault(); });
内容的提问来源于stack exchange,提问作者Marko Polo
相关产品推荐
相关产品推荐

