zoukankan      html  css  js  c++  java
  • 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" />&nbsp;&nbsp;<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" />&nbsp;&nbsp;<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兼容比较好。
    所以再使用的时候,根据实际情况做选择,或者同时兼容。

  • 相关阅读:
    spring-ioc
    Hibernate之二级缓存
    hibernate之HQL语句
    hibernate 多对多关联关系
    hibernate关联关系(一对多)
    Hibernate之主键生成策略
    struts2的CRUD
    struts2的OGNL
    struts2的初步认识
    Maven介绍
  • 原文地址:https://www.cnblogs.com/fei686868/p/9565092.html
Copyright © 2011-2022 走看看