ASP.NET SignalR 系列(八)之跨域推送
前面几章讲的都是同域下的推送和订阅。这种讲讲如何跨域
对于SignalR来说,默认是不允许跨域的,因为安全问题。虽如此,但同时提供了跨域方案。
两种跨域方式:
1:JSONP
2:CORS
JSONP的方式比Cors更不安全。下面分别讲讲怎么使用
一、JSONP方式
服务端设置:
Startup.cs文件
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
//JSONP方式
app.MapSignalR(new HubConfiguration() {EnableJSONP = true});
}
}
然后在全局文件中Global.cs注册,允许jsonp
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes); //注册为允许跨域,JSONP模式需要
var config = new HubConfiguration();
config.EnableJSONP = true; }
}
前端:在其他项目中新建一个html文件
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<link href="/Content/bootstrap.min.css" rel="stylesheet" />
<script src="/Scripts/jquery-1.10.2.min.js"></script>
<script src="http://localhost:59831/Scripts/jquery.signalR-2.3.0.min.js"></script>
<script src="http://localhost:59831/signalr/hub/hubs"></script> <!--指向集线器服务器-->
<meta charset="utf-8" />
<style type="text/css">
body {
margin: 20px;
} .input {
padding-left: 5px;
}
</style>
</head>
<body>
<div>
<h4>这是跨域的页面</h4>
<hr />
<p>
<input type="text" id="content" placeholder="发送内容" class="input" /> <input type="button" value="发送" class="btn btn-sm btn-info" id="btn_send" />
</p> <div>
<h4>接收到的信息:</h4>
<ul id="dataContainer"></ul>
</div>
</div> <script language="javascript">
$(function () {
$.connection.hub.url = 'http://localhost:59831/signalr'; //指定signalR服务器,这个是关键,signalR为固定,系统默认。除非集线器那边重定义。
var chat = $.connection.demoHub; //连接服务端集线器,demoHub为服务端集线器名称,js上首字母须改为小写(系统默认)
//定义客户端方法,此客户端方法必须与服务端集线器中的方法名称、参数均一致。
//实际上是服务端调用了前端的js方法(订阅)
chat.client.show = function (content) {
var html = '<li>' + htmlEncode(content) + "</li>";
$("#dataContainer").append(html);
} //定义推送,跨域启动时,必须指定 jsonp:true
$.connection.hub.start({ jsonp: true })
.done(function () {
$("#btn_send").click(function () {
chat.server.hello($("#content").val()); //将客户端的content内容发送到服务端
$("#content").val("");
});
});
});
//编码
function htmlEncode(value) {
var encodedValue = $('<div />').text(value).html();
return encodedValue;
}
</script>
</body>
</html>
上效果图:

从上图可以看到,用到的域名不同,一个端口号59831 ,一个61625。实现了跨域
第二种:Cors 模式
该模式需要下载Microsoft.Owin.Cors组件,可从Nuget中获取

安装完成后,注册Strartup.cs文件
public void Configuration(IAppBuilder app)
{
////系统默认
//app.MapSignalR();
//JSONP方式
//app.MapSignalR(new HubConfiguration() {EnableJSONP = true}); //Cors跨域模式
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);
});
}
如果需要同时兼容 JSONP,那么将上面EnableJSONP = true 注释取消即可。
cors模式,不需要再global中注册了,如果要兼容JSONP,那么注册还是需要保留
下面上前端:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<link href="/Content/bootstrap.min.css" rel="stylesheet" />
<script src="/Scripts/jquery-1.10.2.min.js"></script>
<script src="http://localhost:59831/Scripts/jquery.signalR-2.3.0.min.js"></script>
<script src="http://localhost:59831/signalr/hub/hubs"></script>
<meta charset="utf-8" />
<style type="text/css">
body {
margin: 20px;
} .input {
padding-left: 5px;
}
</style>
</head>
<body>
<div>
<h4>这是跨域的页面</h4>
<hr />
<p>
<input type="text" id="content" placeholder="发送内容" class="input" /> <input type="button" value="发送" class="btn btn-sm btn-info" id="btn_send" />
</p> <div>
<h4>接收到的信息:</h4>
<ul id="dataContainer"></ul>
</div>
</div> <script language="javascript">
$(function () {
$.connection.hub.url = 'http://localhost:59831/signalr'; //指定signalR服务器
jQuery.support.cors = true; //Cors模式必须设置
var chat = $.connection.demoHub; //连接服务端集线器,demoHub为服务端集线器名称,js上首字母须改为小写(系统默认)
//定义客户端方法,此客户端方法必须与服务端集线器中的方法名称、参数均一致。
//实际上是服务端调用了前端的js方法(订阅)
chat.client.show = function (content) {
var html = '<li>' + htmlEncode(content) + "</li>";
$("#dataContainer").append(html);
} //定义推送,启动时无需再设置jsonp:true
$.connection.hub.start()
.done(function () {
$("#btn_send").click(function () {
chat.server.hello($("#content").val()); //将客户端的content内容发送到服务端
$("#content").val("");
});
});
});
//编码
function htmlEncode(value) {
var encodedValue = $('<div />').text(value).html();
return encodedValue;
}
</script>
</body>
</html>
效果如下图:

至此,两种跨域模式均讲解完成。
cors相对来说安全性比较高,但是对客户端要求比较高,比如低版本的IE不支持。
JSONP的模式安全性较低,但是对低版本IE兼容比较好。
所以再使用的时候,根据实际情况做选择,或者同时兼容。
ASP.NET SignalR 系列(八)之跨域推送的更多相关文章
- Asp.net SignalR 实现服务端消息实时推送到所有Web端
ASP .NET SignalR是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.实际上 Asp.net SignalR 2 实现 服务端消息推送到Web端, 更加 ...
- asp.net core 系列之允许跨域访问-1(Enable Cross-Origin Requests:CORS)
接上篇的允许跨域 4.CORS 策略(Policy)的选项 这里讲解Policy可以设置的选项: 设置允许的访问源 设置允许的HTTP methods 设置允许的请求头(request header) ...
- asp.net core 系列之允许跨域访问2之测试跨域(Enable Cross-Origin Requests:CORS)
这一节主要讲如何测试跨域问题 你可以直接在官网下载示例代码,也可以自己写,我这里直接使用官网样例进行演示 样例代码下载: Cors 一.提供服务方,这里使用的是API 1.创建一个API项目.或者直接 ...
- Signalr指定Websocket方式跨域数据传输
跨域通俗理解就是两个域名后面的web服务地址,即都是独立的网站.现实业务的情况会有很多需要跨域推送数据的情况, 比如类似饿了么商户后台会收到客户端确认订单后,后台服务会推送一条订单消息给商户前台. S ...
- 《ASP.NET SignalR系列》第四课 SignalR自托管(不用IIS)
从现在开始相关文章请到: http://lko2o.com/moon 接着上一篇:<ASP.NET SignalR系列>第三课 SignalR的支持平台 一.概述 SignalR常常依托于 ...
- 《ASP.NET SignalR系列》第一课 认识SignalR
从现在开始相关文章请到: http://lko2o.com/moon 一.概述 ASP.NET signalr对ASP.NET开发者来说是一个新的程序库,它能让我们更加容易便捷地开发实时通信功能; s ...
- 如何在ASP.NET Core中实现CORS跨域
注:下载本文的完整代码示例请访问 > How to enable CORS(Cross-origin resource sharing) in ASP.NET Core 如何在ASP.NET C ...
- 《ASP.NET SignalR系列》第五课 在MVC中使用SignalR
接着上一篇:<ASP.NET SignalR系列>第四课 SignalR自托管(不用IIS) 一.概述 本教程主要阐释了如何在MVC下使用ASP.NET SignalR. 添加Signal ...
- 《ASP.NET SignalR系列》第三课 SignalR的支持平台
从现在开始相关文章请到: http://lko2o.com/moon 接着第二课:<ASP.NET SignalR系列>第二课 SignalR的使用说明 一.服务器系统要求 SignalR ...
随机推荐
- 【JavaScript】内部与外部引入方式
1.内部引入方式: script的type属性默认为"text/javascript",可以不写 <script type="text/javascript&quo ...
- 使用pipenv管理虚拟环境
使用pipenv管理虚拟环境 安装 pip install pipenv 命令介绍 pipenv --help Usage: pipenv [OPTIONS] COMMAND [ARGS]... Op ...
- C#中的函数(三)参数传递及返回值
接前面二篇,继续开始新的研究 前面忘了说什么是主调函数与被调函数 主调函数:执行调用其它函数语句所在的函数 被调函数:被其它函数所调用的函数 简单说就是一个是发起调用者,另一个是被调用者 写个小例子说 ...
- 2.1 自动内存管理机制--Java内存区域与内存溢出异常
自动内存管理机制 第二章.Java内存区域与内存溢出异常 [虚拟机中内存如何划分,以及哪部分区域.什么样代码和操作会导致内存溢出.各区域内存溢出的原因] 一.运行时数据区域 Java虚拟机所管理的内存 ...
- java 读写Parquet格式的数据 Parquet example
import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOExce ...
- C# 不包含 AsEnumerable 的定义
引用 System.Data.DataSetExtensions 引用右键 ->添加引用 ->搜索 DataSetExtensions ->添加 注意版本
- Rpm Creating Subpackages
转自:http://ftp.rpm.org/max-rpm/s1-rpm-subpack-spec-file-changes.html Spec File Changes For Subpackage ...
- Java实现递归阶乘
public class Factorial{ public static void main(String[] args){ for (int i = -5; i <= 5; i++) { S ...
- adb--环境安装
前戏 我们在做Android自动化的时候,adb命令是必不可少的,比如我们要获取一个包名,使用adb往手机上安装软件,获取activity等等,都要用到adb命令.而模拟器在我们没有手机测试的时候,可 ...
- Unix/Linux系统下的nobody用户是什么?
1.Windows系统在安装后会自动建立一些用户帐户,在Linux系统中同样有一些用户帐户是在系统安装后就有的,就像Windows系统中的内置帐户一样. 2.它们是用来完成特定任务的,比如nobody ...