一步一步學習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 下載

相關文章
相關標籤/搜索