.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文件),將這個文件下載下來,那么瀏覽器會執行這個文件,而這個文件就包含別的站點的訪問數據.具體實現方法如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM