MVC跨域CORS擴展

       通常的基於瀏覽器跨域的主要解決方法有這麼幾種:1.JSONP       2.IFrame方式    3.經過flash實現  4.CORS跨域資源共享  ,這裏咱們主要關注的是在MVC裏面的CORS跨域,其他的方式你們能夠在網上找到相關的知識看一下。web

      

  •  CORS的原理:
     CORS定義一種跨域訪問的機制,可讓AJAX實現跨域訪問。CORS 容許一個域上的網絡應用向另外一個域提交跨域 AJAX 請求。實現此功能很是簡單,只需由服務器發送一個響應標頭便可。
      context.HttpContext.Response.AppendHeader("Access-Control-Allow-Origin", origin);
  • CORS瀏覽器支持狀況以下圖:
      
    
        也就是說除了IE8如下版本的瀏覽器不支持,其他的基於W3c標準的大部分都是支持的。
   

通常的針對ASP.NET MVC,cors跨域訪問,只須要在web.config中添加以下的內容便可跨域

<system.webServer>瀏覽器

<httpProtocol> 服務器

<customHeaders> 網絡

<add name="Access-Control-Allow-Origin" value="*" /> cors

<add name="Access-Control-Allow-Headers" value="Content-Type" /> less

<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" /> ide

</customHeaders> post

</httpProtocol> 測試

<handlers>

<remove name="ExtensionlessUrlHandler-Integrated-4.0" />

<remove name="OPTIONSVerbHandler" />

<remove name="TRACEVerbHandler" />

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

</handlers>

</system.webServer>

 

可是這種全局設置存在侷限性,由於你沒法有選擇性的設置能夠跨域訪問你本站的站點,因此就想到能不能經過特性標記控制器,或者標記控制器中的方法來設置跨域訪問權限。

好比以下的方式

[ControllerAllowOrigin(AllowSites=new string[] { "aa.com" ,"bb.com"})]

public    class          TestController

     {

  

     }

    這樣你能夠設置aa.com,bb.com跨域請求你站點TestController裏面的任何數據接口方法

   或者是以下方式:

 

public    class          TestController

     {

       [ActionAllowOrigin(AllowSites=new string[] { "aa.com" ,"bb.com"})]

        public   JsonResult   Test()

        {

 

        }

     }

    設置aa.com,bb.com只能跨域請求你站點裏面的TestController中的Test方法。

    這樣的話,咱們控制起來就更加靈活方便,容許跨域訪問本站的,在AllowSites裏面添加地址就好了。

  1.  基於控制器的跨域訪問設置,這邊我定義了一個ControllerAllowOriginAttribute,繼承於AuthorizeAttribute

  代碼以下:

    public class ControllerAllowOriginAttribute : AuthorizeAttribute
    {
        public string[] AllowSites { get; set; }
        public override void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext)
        {
            AllowOriginAttribute.onExcute(filterContext, AllowSites);
        }

    }

 

2.基於方法的跨域訪問設置,我定義了一個ActionAllowOriginAttribute,繼承於ActionFilterAttribute,

  代碼以下:

 public class ActionAllowOriginAttribute : ActionFilterAttribute
    {
        public string[] AllowSites { get; set; }
        public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
        {
            AllowOriginAttribute.onExcute(filterContext, AllowSites);
            base.OnActionExecuting(filterContext);
        }
    }

 

核心代碼其實很簡單,就這麼幾行:

public class AllowOriginAttribute
    {
        public static void onExcute(ControllerContext context, string[] AllowSites)
        {
            var origin = context.HttpContext.Request.Headers["Origin"];
            Action action = () =>
            {
                context.HttpContext.Response.AppendHeader("Access-Control-Allow-Origin", origin);

            };
            if (AllowSites != null && AllowSites.Any())
            {
                if (AllowSites.Contains(origin))
                {
                    action();
                }
            }
            
        }
    }

其中設置跨域訪問權限的代碼就是這一段HttpContext.Response.AppendHeader("Access-Control-Allow-Origin", origin);

 

完整的代碼以下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace IocTEST.Common
{
    public class AllowOriginAttribute
    {
        public static void onExcute(ControllerContext context, string[] AllowSites)
        {
            var origin = context.HttpContext.Request.Headers["Origin"];
            Action action = () =>
            {
                context.HttpContext.Response.AppendHeader("Access-Control-Allow-Origin", origin);

            };
            if (AllowSites != null && AllowSites.Any())
            {
                if (AllowSites.Contains(origin))
                {
                    action();
                }
            }
            

        }
    }

    public class ActionAllowOriginAttribute : ActionFilterAttribute
    {
        public string[] AllowSites { get; set; }
        public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
        {
            AllowOriginAttribute.onExcute(filterContext, AllowSites);
            base.OnActionExecuting(filterContext);
        }
    }
    public class ControllerAllowOriginAttribute : AuthorizeAttribute
    {
        public string[] AllowSites { get; set; }
        public override void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext)
        {
            AllowOriginAttribute.onExcute(filterContext, AllowSites);
        }

    }


  
}
View Code

 

調用方式

  [ControllerAllowOrigin(AllowSites = new string[] { "http://www.cnblogs.com" })]
    public class HomeController : Controller
    {

   
        public JsonResult Test()
        {
            return Json(new { name = "aaa" }, JsonRequestBehavior.AllowGet);
        }

   }

 

 

  public class HomeController : Controller
    {

        [ActionAllowOrigin(AllowSites = new string[] { "http://www.cnbeta.com" })]
        public JsonResult Test()
        {
            return Json(new { name = "aaa" }, JsonRequestBehavior.AllowGet);
        }

   }

 

測試的時候,能夠將須要跨域訪問你本地localhost站點的網站打開,而後F12打開firebug,在console裏面輸入$.post('http://localhost:80/',{},function(){})或者

$.get('http://localhost:80/',{},function(){})  觀察請求狀態。

相關文章
相關標籤/搜索