ASP.NET MVC中設置跨域


ASP.NET MVC中設置跨域

1、什么是跨域請求

js禁止向不是當前域名的網站發起一次ajax請求,即使成功respone了數據,但是你的js仍然會報錯。這是JS的同源策略限制,JS控制的並不是我們網站編程出現了問題。客戶端(網頁)和后台編程都可以有效解決這個問題。客戶端可以通過JSONP來完成跨域訪問;在ES6中為了解除同源策略問題,想出一個辦法:當被請求網站為響應頭respone添加了一個名為Access-Control-Allow-Origin的header,設置其值等於發起請求網站的域名地址的話,這次請求被視為允許。其中Access-Control-Allow-Origin的值為*時表示允許所有網站的跨域請求。

2、程序中添加Header頭允許客戶端跨域請求

這里有很多方法可以方法可以在返回數據時添加header頭。

請注意:同名Header可以有多個 ,但是運行時使用的是第一個,addHeader添加時,如果同名header已存在,則追加至原同名header后面(不起作用),setHeader,如果同名header已存在,則覆蓋一個同名header。

在action中添加代碼

HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Origin", "*");

在webconfig添加應用程序配置:

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <!-- 先移除后添加,確保起作用 -->
      <remove name="Access-Control-Allow-Origin" />
      <remove name="Access-Control-Allow-Headers" />
      <remove name="Access-Control-Allow-Methods" />
      <add name="Access-Control-Allow-Origin" value="*" />
      <add name="Access-Control-Allow-Headers" value="Content-Type" />
      <add name="Access-Control-Allow-Methods" value="*" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

添加action過濾器

不論webapi還是mvc的action,我們都可以重寫ActionFilterAttribute過濾器的OnException方法來在action執行完成之后,為http響應添加header頭;OnException方法意為在action執行完成之后進行的操作。這個過濾器可以添加在action或者controller上,但是這樣就要為每一個action或者controller打上這個過濾器,這里將我們重寫的action過濾器添加在了全局的過濾器中,這樣,每一個action在執行完成之后都會觸發這個過濾器,這里以webapi為例。新建類:

    /// <summary>
    /// 跨域
    /// </summary>
    public class Cores:ActionFilterAttribute
    {
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            base.OnActionExecuted(actionExecutedContext);
            actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin","*");
        }
    }

代碼中注冊過濾器

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API 配置和服務
            // 將 Web API 配置為僅使用不記名令牌身份驗證。
            config.SuppressDefaultHostAuthentication();
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

            // Web API 路由
            config.MapHttpAttributeRoutes();
            config.Filters.Add(new Cores());
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }

在Starpup.cs類中設置header頭

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Owin;
using Owin;
using System.Web;

[assembly: OwinStartup(typeof(WebApiTest.Startup))]

namespace WebApiTest
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // 不能使用這種方式添加必須使用app的相應方法或者中間件實現
            // HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");

            //app.UseWebApi();
            app.Use(async (context,next)=> {
                context.Response.Headers.Set("Access-Control-Allow-Origin", "*");
                await next();
            });
        }
    }
}

startup.cs類是應用啟動類,我本來以為直接在方法中直接把HttpContext.Current.Response.AddHeader添加一個頭就行了,但是發現不行,必須通過參數app才能成功設置響應頭,后來我才知道,這個startup.cs類遠不止看到的那么簡單!拿出來可以當作好比一本書的一個章節來講了!以后再深入了解這個類。

3、引入Script標簽獲取數據

一些JSONP之類的客戶端跨域請求就不說了,最近發現了構造Script標簽也可以作為獲取數據的方法,很開心。

即使服務端不設置允許跨域的header頭,js也可以變通獲取數據,不過仍然需要服務端的配合。

這個原理是;當通過script標簽的src地址引入某個資源的JS代碼的時候,就相當於src地址的JS代碼直接就在本地一樣。相應的,其他地址的js變量也會引入當前頁面
比如百度地圖的JsAPI
比如雅虎獲取IP地址的接口
接口:http://pv.sohu.com/cityjson
返回JS代碼:var returnCitySN = {"cip": "115.238.95.194", "cid": "330100", "cname": "浙江省杭州市"};
頁面引入
<script src="http://pv.sohu.com/cityjson"></script>
然后console.log(returnCitySN)可以直接使用。
這就提供了思路,

var script = document.createElement("script"),
script.src = "http://pv.sohu.com/cityjson";
script.onload=()=>{
console.log(returnCitySN);
}

但是缺點是,服務端必須返回的是JS代碼。


免責聲明!

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



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