zoukankan      html  css  js  c++  java
  • .Net 站点跨域问题及解决方法

    一、什么是站点跨域

    了解跨域之前, 先了解下什么同源策略?
    百度百科:
    同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
    同源:同一个协议, 同一个主机, 同一个端口 即同一个站点, 比如说IIS服务器, 一个站点只能绑定一个端口

    那为什么需要同源策略的支持呢?
    因为假设你已经登陆一个站点, 服务器已经将一些敏感信息返回到了客户端, 如果此时你的站点代码中有一段访问其他站点的代码, 这段代码又是获取用户的铭感信息, 又比如说用户在访问银行网站,并且没有登出。然后他又去了任意的其他网站,
    刚好这个网站有恶意的js代码,在后台请求银行网站的信息。因为用户目前仍然是银行站点的登陆状态,那么恶意代码就可以在银行站点做任意事情。例如,获取你的最近交易记录,创建一个新的交易等等。那是相当不安全的.
    所以同源策略是相当重要的.即如果访问了一个站点, 那么用户在访问这个站点的所有内容必须是这个站点的内容, 不允许访问其他站点的内容.

    二、"同源政策"限制的功能

    随着互联网的发展,"同源政策"越来越严格。目前,如果非同源,共有三种行为受到限制。

    (1) Cookie、LocalStorage 和 IndexDB 无法读取。

    (2) DOM 无法获得。

    (3) AJAX 请求不能发送。

    虽然这些限制是必要的,但是有时很不方便,合理的用途也受到影响。

    三、为什么要规避同源策略

    1、Cookie问题

    假设我们有一个站点,由于业务的扩展,一个站点无法承受这么大的业务量,常规的做法是将业务拆分,拆分成不同的站点.但是理论上拆分出来的站点还是归属于原来的站点,因为逻辑上这些站点属于一个应用程序,所以我们需要使用多级域名的技术,给主站点分配一个主域名,其他的站点分配该主域名的子域名,集体请参考IIS 站点部署多级域名.

    但是由于"同源策略"的影响,其中的一个业务站点无法共享其它站点的Cookie,因为它们只是一级域名相同,二级域名并不相同,但是理论上它们时同一个应用程序,所以Cookie必须共享.

    问题重现,在主站点的MVC控制器的Index方法写入一个Cookie信息,代码如下:

            public ActionResult Index()
            {
                var cookie = new HttpCookie("userInfo", "xiaochao");
                cookie.Expires = DateTime.Now.AddDays(1);//设置cookie一天后过期
                Response.SetCookie(cookie);
                return View();
            }

    在主站点的Index页面下读取cookie,代码如下:

    <script>
        $(function () {
            //输出在主站点设置的cookie
            $(function () {
                //输出cookie
                var username = document.cookie.split(";")[0].split("=")[1];
                if (username) {
                    alert(username);
                }
                else {
                    alert("cookie没有写入");
                }
            });
        });

    注意在打开浏览器前,请先清空浏览器缓存,主站点浏览器输出:

    ok,Cookie正常输出,接着打开业务站点1,js代码和上面的一样

    ok,问题很明显,主站点并没有将cookie共享到业务站点,所以这个问题必须解决.

    解决方案如下:

    (1)、服务器端设置Cookie的Domain属性 

    通过主站点服务器端(不一定在主站点,也可以是业务站点,亲测有效,这里不做演示)设置Cookie的Domain属性为一级域名,这样所有的在一级域名下的二级域名站点都可以共享Cookie,代码如下:

            public ActionResult Index()
            {
                var cookie = new HttpCookie("userInfo", "xiaochao");
                cookie.Expires = DateTime.Now.AddDays(1);//设置cookie一天后过期
                cookie.Domain = "a.com";//设置Domain属性,这样这个域名下的所有的子域名,所有站点都共享Cookie
                Response.SetCookie(cookie);
                return View();
            }

    主站点输出:

    业务站点1输出:

    ok,说明在Cookie设置生效了,所有的站点共享了Cookie.

    (2)、客户端Js脚本设置

    3、.Net 站点下跨域问题的重现

    现在有两个站点,一个MVC站点,一个WebApi站点

    此时有个业务,MVC站点需要访问Api站点下面的一个Json方法,拿到对应的业务数据

    Api站点的方法如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace SiteApi.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                ViewBag.Title = "Home Page";
    
                return View();
            }
    
            /// <summary>
            /// 给MVC站点调用的方法
            /// </summary>
            /// <returns></returns>
            [HttpPost]
            public ActionResult GetData()
            {
                return Json("666");
            }
        }
    }

    MVC页面的调用代码如下:

    <script src="~/Scripts/jquery-1.10.2.js"></script>
    <script>
        $(function () {
            $.post("http://localhost:50187/Home/GetData", function (data) {
                alert(data);
            });
        });
    </script>

    运行站点效果如下:

    数据没有出来,打开控制台发现了这个Error。百度提示,浏览器出现跨域行为,需要添加Asscss-COntrol-Allow-Origin头.


    4、为什么要规避跨域
    先说说为什么要规避跨域?
    上面的例子可以说明,且假设有一个应用集群,我们建设了一个用户中心,该用户中心提供一些用户验证的功能,如登陆校验、权限等功能.那必须的,这个用户中心是以站点的形式存在,而应用集群中所有的应用必须能访问该用户中心站点,来校验用户的可用性,
    但是用户中心站点对于应用集群中所有的应用来说都属于外部应用,所以违反了同源策略,但是这个功能必须要实现.所以这种情况下,必须采用技术手段来规避同源策略.


    5、解决方案

    (1)、跨域资源共享 CORS 技术

    Ajax请求受限于同源策略,而这种技术能解决这种限制.但是需要服务器和浏览器的协作,IE浏览器不能低于IE10.

    (1)、Jsonp技术

    下面用Jsonp技术来解决这个问题.在了解这个技术之前,你需要知道虽然同源策略不允许跨域Ajax请求,代码支持跨域的文件访问,这些文件包括图片、Js文件等.这里我们就可以用特定的Ajax请求去访问一个Js文件(也可以是html文件),将这个文件下载下来,那么浏览器会执行这个文件,而这个文件就包含别的站点的访问数据.具体实现方法如下:

  • 相关阅读:
    使用 ASP.NET Core MVC 创建 Web API(五)
    使用 ASP.NET Core MVC 创建 Web API(四)
    使用 ASP.NET Core MVC 创建 Web API(三)
    使用 ASP.NET Core MVC 创建 Web API(二)
    使用 ASP.NET Core MVC 创建 Web API(一)
    学习ASP.NET Core Razor 编程系列十九——分页
    学习ASP.NET Core Razor 编程系列十八——并发解决方案
    一个屌丝程序猿的人生(九十八)
    一个屌丝程序猿的人生(九十七)
    一个屌丝程序猿的人生(九十五)
  • 原文地址:https://www.cnblogs.com/GreenLeaves/p/9931446.html
Copyright © 2011-2022 走看看