一步一步学习SignalR进行实时通讯_3_经过CORS解决跨域

原文: 一步一步学习SignalR进行实时通讯_3_经过CORS解决跨域

一步一步学习SignalR进行实时通讯\_3_经过CORS解决跨域 javascript

SignalRhtml


前言

这周工做比较忙,一直没有时间学习SignalR,大体但愿一周能写一篇关于SignalR的文章。上一篇用Persistent Connections方式实现了个简单的在线聊天功能,此次咱们继续深刻学习。java

关于start()的补充

在上一篇文章里前台的html页面咱们经过几句javascript建立了一个,代码以下,也能够下载上次的源码。jquery

  
  
  
  
<!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()来开启链接并在链接完成时处理咱们须要处理的事件。
若是你将如下代码json

  
  
  
  
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对象进行相关配置。app

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_1echo.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 Programming in Microsoft ASP.NET pdf 下载

相关文章
相关标签/搜索