一步一步学习SignalR进行实时通信_3_通过CORS解决跨域
原文:一步一步学习SignalR进行实时通信_3_通过CORS解决跨域
一步一步学习SignalR进行实时通信\_3_通过CORS解决跨域
SignalR
前言
这周工作比较忙,一直没有时间学习SignalR,大致希望一周能写一篇关于SignalR的文章。上一篇用Persistent Connections方式实现了个简单的在线聊天功能,这次我们继续深入学习。
关于start()的补充
在上一篇文章里前台的html页面我们通过几句javascript创建了一个,代码如下,也可以下载上次的源码。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>persistent connections</title>
<script src="Scripts/jquery-1.10.2.min.js"></script>
<script src="Scripts/jquery.signalR-2.0.0.min.js"></script>
</head>
<body>
<h1>Echo service</h1>
<div>
<input type="text" id="text" />
<button id="send">Send</button>
</div>
<script>
$(function () {
var connection = $.connection("/echo");
connection.logging = true;
connection.received(function (data) {
$("body").append(data + "<br />");
});
connection.error(function (err) {
alert("存在一个错误. \n" +
"Error: " + err.message);
});
connection.start().done(function () {
$("#send").click(function () {
connection.send($("#text").val());
$("#text").val("").focus();
});
});
});
</script>
</body>
</html>
这里需要做些说明:通过代码var connection = $.connection("/echo");
我们创建了一个连接,通过connection.start().done()
来开启连接并在连接完成时处理我们需要处理的事件。
如果你将以下代码
connection.start().done(function () {
connection.send('Hi');
});
分成2部分写,如:
connection.start();
connection.send('Hi');
那么你必须注意:
虽然你在connection.send()
之前调用了connection.start()
开启了连接,但是connection.start()
是一个异步方法,意味着有可能你在调用connection.send()
时connection并未开启,那么项目将会报错。
正确方法如之前代码所示,再加上一段开启失败的代码:
var connection = $.connection("/echo");
connection.start(function() {
// 连接开启成功才会进入这里
connection.send("Hi");
}).fail(function() {
//连接开启失败则进入这里
alert("服务开启失败");
});
跨域解决方案
上篇文章里有同学问到跨域的问题,那么在接下来的时间我将会带着大家一起学习。
在SignalR解决跨域,有两种方式:第一种是JSONP,第二种是CORS。
JSONP
如果你的服务必须要支持老版本的浏览器,那么JSONP是唯一选择,否则处于安全的考虑这并不被推荐,具体什么安全因素我并不知晓(有同学知道的话可以说明下),基于快速学习的情况下,我们无需纠缠于此。服务器默认会禁用此功能,我们可以通过初始化时提供一个ConnectionConfiguration对象并设置EnableJSONP属性为true来激活此功能。
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new ConnectionConfiguration()
{
EnableJSONP = true
};
app.MapSignalR<EchoConnection>("/echo", config);
}
}
我想这几句代码应该很好理解,我们在前面提到过MapSignalR<TConnection>()
有许多重载方法,这是另一个重载方法通过提供一个ConnectionConfiguration
对象进行相关配置。
CORS
CORS是一个独立的框架,它可以很方便的解决跨域问题,通过Nuget安装
安装命令:Install-Package microsoft.owin.cors
CORS是通过Owin实现的,所以我们需要在项目启动时对他进行一些配置,和做SignalR映射一样实在Startup中进行配置。
public class Startup
{
public void Configuration(IAppBuilder app)
{
//app.MapSignalR<EchoConnection>("/echo");
app.Map("/echo",
map => {
map.UseCors(CorsOptions.AllowAll);
map.RunSignalR<EchoConnection>();
}
);
}
}
代码应该也不难,这次我们通过app.Map()
进行映射,第一个参数是映射的地址,第二个参数是一个lambda表达式,通过UseCors(CorsOptions.AllowAll)
允许允许跨域。
CORS跨域演示
JSONP我不做演示了有兴趣的可以自己尝试下,接下来我这里做一个通过CORS来进行跨域聊天。首先我讲上次的项目复制一份,省得再重新打代码,并将复制出来的项目名称由SignalR_1改为SignalR_2_CORS。
项目目录如下图所示:
省得麻烦,我把SignalR_1部署在IIS上面,这就充当了 一个远程的SignalR服务。
部署成功后,如图所示:
此时我们讲SignalR_2_CORS项目稍作修改
1. 将Startup中的映射删去,此时SignalR_2_CORS已不做SignalR服务器了,只做客户端来连接SignalR_1提供的服务
2. 将echo中的var connection = $.connection("/echo");
改为
var connection = $.connection("http://127.0.0.1:8083/echo");
然后运行SignalR_2_CORS中的echo页面,结果如图所示:
出现了一个错误,这个错误提示是我们自己写的
因为我们的SignalR_1并没有允许跨域连接,那么在SignalR_2_CORS中当然无法连接,接下来我们在项目一中允许跨域连接。
重新编译项目一后再刷新下SignalR_1的echo.html页面,注意我们这个页面地址
然后刷新下SignalR_2_CORS的页面,注意这个地址
连接成功,没有报错了,发送个消息试试看(●ˇ∀ˇ●)
结束语
这里通过CORS实现了SignalR的跨域问题,跨域如此简单赶快试试吧 。
注意:在通过Nuget安装CORS包时,我这边提示了Unable to find package 'Microsoft.AspNet.Cors'我已经FQ了,所以这个应该不是需要FQ才能下载,但是在Nuget页面中搜索确实有这个包,具体什么原因引起的我也不清楚,如果你有碰到这个问题请下载解压并添加引用即可,由于
Microsoft.AspNet.Cors
依赖于Microsoft.AspNet.Cors
,所以里面的2个包都要添加引用
参考文献
一步一步学习SignalR进行实时通信_3_通过CORS解决跨域的更多相关文章
- 一步一步学习SignalR进行实时通信_1_简单介绍
一步一步学习SignalR进行实时通信\_1_简单介绍 SignalR 一步一步学习SignalR进行实时通信_1_简单介绍 前言 SignalR介绍 支持的平台 相关说明 OWIN 结束语 参考文献 ...
- 一步一步学习SignalR进行实时通信_8_案例2
原文:一步一步学习SignalR进行实时通信_8_案例2 一步一步学习SignalR进行实时通信\_8_案例2 SignalR 一步一步学习SignalR进行实时通信_8_案例2 前言 配置Hub 建 ...
- 一步一步学习SignalR进行实时通信_9_托管在非Web应用程序
原文:一步一步学习SignalR进行实时通信_9_托管在非Web应用程序 一步一步学习SignalR进行实时通信\_9_托管在非Web应用程序 一步一步学习SignalR进行实时通信_9_托管在非We ...
- 一步一步学习SignalR进行实时通信_7_非代理
原文:一步一步学习SignalR进行实时通信_7_非代理 一步一步学习SignalR进行实时通信\_7_非代理 SignalR 一步一步学习SignalR进行实时通信_7_非代理 前言 代理与非代理 ...
- 一步一步学习SignalR进行实时通信_5_Hub
原文:一步一步学习SignalR进行实时通信_5_Hub 一步一步学习SignalR进行实时通信\_5_Hub SignalR 一步一步学习SignalR进行实时通信_5_Hub 前言 Hub命名规则 ...
- 一步一步学习SignalR进行实时通信_6_案例
原文:一步一步学习SignalR进行实时通信_6_案例 一步一步学习SignalR进行实时通信\_6_案例1 一步一步学习SignalR进行实时通信_6_案例1 前言 类的定义 各块功能 后台 上线 ...
- 一步一步学习SignalR进行实时通信_4_Hub
原文:一步一步学习SignalR进行实时通信_4_Hub 一步一步学习SignalR进行实时通信\_4_Hub SignalR 一步一步学习SignalR进行实时通信_4_Hub 前言 创建Hub 配 ...
- 一步一步学习SignalR进行实时通信_2_Persistent Connections
原文:一步一步学习SignalR进行实时通信_2_Persistent Connections 一步一步学习SignalR进行实时通信\_2_Persistent Connections Signal ...
- 从.Net到Java学习第十二篇——SpringBoot+JPA提供跨域接口
从.Net到Java学习系列目录 最近又撸了半个月的前端代码,做app离线存储,然后又花了一周去将过去的wcf项目转webapi,java又被落下了,总感觉我特么像斗地主中的癞子牌,变来变去..... ...
随机推荐
- lightoj 1079 Just another Robbery
题意:给出银行的个数和被抓概率上限.在给出每个银行的钱和抢劫这个银行被抓的概率.求不超过被抓概率上线能抢劫到最多的钱. dp题,转移方程 dp[i][j] = min(dp[i-1][j] , dp[ ...
- 加密传输SSL协议5_Hash Function
怎么对一个大的文件进行签名,因为文件比较大,非对称签名很慢.那么想,我能把这个大的文件通过一种函数变换,变成一个和源文件唯一对应的的小的文件吗?答案是可以的. Hash Function 这里任何的文 ...
- LNMP卸载
先停掉所有服务 service mysql stop service php-fpm stop service nginx stop killall mysql* killall php-fpm* k ...
- textarea 在浏览器中固定大小和禁止拖动
HTML 标签 textarea 在大部分浏览器中只要指定行(rows)和列(cols)属性,就可以规定 textarea 的尺寸,大小就不会改变,不过更好的办法是使用 CSS 的 height 和 ...
- OC中NSArray的使用
不可变数组类容器类,管理一组对象类型的数据. 元素是有序的,索引值从0开始 数组中存储的元素必须是对象,类型任意. 创建数组对象,使⽤用实例初始化或便利构造器.获取元素个数.根据索引值获取对 ...
- python进阶--打包为exe文件
一.Python打包为EXE文件有不少方案,比较常用的有下面两种方式: 1.使用py2exe 详细介绍:http://www.cnblogs.com/jans2002/archive/2006/09/ ...
- SQL Server 表压缩
表压缩有三个选项 1.page 2.row 3.none ----------------------------------------------------------------------- ...
- PHP之闭包详解
匿名函数提到闭包就不得不想起匿名函数,也叫闭包函数(closures),貌似PHP闭包实现主要就是靠它.声明一个匿名函数是这样: $func = function() { }; //带结束符 可以看到 ...
- Unix/Linux环境C编程入门教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建
1. openSUSE是一款优秀的linux. 2.选择默认虚拟机 3.选择稍后安装操作系统 4.选择linux opensuse 5. 选择默认虚拟机名称 6.设置处理器为双核. 7.内存设置为2 ...
- C++ 栈的实现
#ifndef _STACK_H #define _STACK_H #pragma once template< class T >class Stack{public: Stack( v ...