国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > C# > 正文

C# WebApi CORS跨域問(wèn)題解決方案

2019-10-29 19:59:38
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

前言:上篇總結(jié)了下WebApi的接口測(cè)試工具的使用,這篇接著來(lái)看看WebAPI的另一個(gè)常見(jiàn)問(wèn)題:跨域問(wèn)題。本篇主要從實(shí)例的角度分享下CORS解決跨域問(wèn)題一些細(xì)節(jié)。

一、跨域問(wèn)題的由來(lái)

同源策略:出于安全考慮,瀏覽器會(huì)限制腳本中發(fā)起的跨站請(qǐng)求,瀏覽器要求JavaScript或Cookie只能訪(fǎng)問(wèn)同域下的內(nèi)容。

正是由于這個(gè)原因,我們不同項(xiàng)目之間的調(diào)用就會(huì)被瀏覽器阻止。比如我們最常見(jiàn)的場(chǎng)景:WebApi作為數(shù)據(jù)服務(wù)層,它是一個(gè)單獨(dú)的項(xiàng)目,我們的MVC項(xiàng)目作為Web的顯示層,這個(gè)時(shí)候我們的MVC里面就需要調(diào)用WebApi里面的接口取數(shù)據(jù)展現(xiàn)在頁(yè)面上。因?yàn)槲覀兊腤ebApi和MVC是兩個(gè)不同的項(xiàng)目,所以運(yùn)行起來(lái)之后就存在上面說(shuō)的跨域的問(wèn)題。

二、跨域問(wèn)題解決原理

CORS全稱(chēng)Cross-Origin Resource Sharing,中文全稱(chēng)跨域資源共享。它解決跨域問(wèn)題的原理是通過(guò)向http的請(qǐng)求報(bào)文和響應(yīng)報(bào)文里面加入相應(yīng)的標(biāo)識(shí)告訴瀏覽器它能訪(fǎng)問(wèn)哪些域名的請(qǐng)求。比如我們向響應(yīng)報(bào)文里面增加這個(gè)Access-Control-Allow-Origin:http://localhost:8081,就表示支持http://localhost:8081里面的所有請(qǐng)求訪(fǎng)問(wèn)系統(tǒng)資源。其他更多的應(yīng)用我們就不一一列舉,可以去網(wǎng)上找找。

三、跨域問(wèn)題解決細(xì)節(jié)

下面我就結(jié)合一個(gè)簡(jiǎn)單的實(shí)例來(lái)說(shuō)明下如何使用CORS解決WebApi的跨域問(wèn)題。

1、場(chǎng)景描述

我們新建兩個(gè)項(xiàng)目,一個(gè)WebApi項(xiàng)目(下圖中WebApiCORS),一個(gè)MVC項(xiàng)目(下圖中Web)。WebApi項(xiàng)目負(fù)責(zé)提供接口服務(wù),MVC項(xiàng)目負(fù)責(zé)頁(yè)面呈現(xiàn)。如下:

C#,WebApi,CORS,跨域

其中,Web與WebApiCORS端口號(hào)分別為“27239”和“27221”。Web項(xiàng)目需要從WebApiCORSS項(xiàng)目里面取數(shù)據(jù),很顯然,兩個(gè)項(xiàng)目端口不同,所以并不同源,如果使用常規(guī)的調(diào)用方法肯定存在一個(gè)跨域的問(wèn)題。

簡(jiǎn)單介紹下測(cè)試代碼,Web里面有一個(gè)HomeController

public class HomeController : Controller  {    // GET: Home    public ActionResult Index()    {      return View();    }  }

對(duì)應(yīng)的Index.cshtml

<html><head>  <meta name="viewport" content="width=device-width" />  <title>Index</title>  <script src="~/Content/jquery-1.9.1.js"></script>  <link href="~/Content/bootstrap/css/bootstrap.css" rel="external nofollow" rel="stylesheet" />  <script src="~/Content/bootstrap/js/bootstrap.js"></script>  <script src="~/Scripts/Home/Index.js"></script></head><body>  測(cè)試結(jié)果:<div id="div_test">   </div></body></html>

Index.js文件

var ApiUrl = "http://localhost:27221/";$(function () {  $.ajax({    type: "get",    url: ApiUrl + "api/Charging/GetAllChargingData",    data: {},    success: function (data, status) {      if (status == "success") {        $("#div_test").html(data);      }    },    error: function (e) {      $("#div_test").html("Error");    },    complete: function () {    }  });});

WebApiCORS項(xiàng)目里面有一個(gè)測(cè)試的WebApi服務(wù)ChargingController

public class ChargingController : ApiController  {    /// <summary>    /// 得到所有數(shù)據(jù)    /// </summary>    /// <returns>返回?cái)?shù)據(jù)</returns>    [HttpGet]    public string GetAllChargingData()    {      return "Success";    }  }

配置WebApi的路由規(guī)則為通過(guò)action調(diào)用。WebApiConfig.cs文件

public static class WebApiConfig  {    public static void Register(HttpConfiguration config)    {      // Web API 路由      config.MapHttpAttributeRoutes();      config.Routes.MapHttpRoute(        name: "DefaultApi",        routeTemplate: "api/{controller}/{action}/{id}",        defaults: new { id = RouteParameter.Optional }      );    }  }

2、場(chǎng)景測(cè)試

1)我們不做任何的處理,直接將兩個(gè)項(xiàng)目運(yùn)行起來(lái)。看效果如何

IE瀏覽器:

C#,WebApi,CORS,跨域

谷歌瀏覽器:

C#,WebApi,CORS,跨域

這個(gè)結(jié)果另博主也很吃驚,不做任何跨域處理,IE10、IE11竟然可以直接請(qǐng)求數(shù)據(jù)成功,而同樣的代碼IE8、IE9、谷歌瀏覽器卻不能跨域訪(fǎng)問(wèn)。此原因有待查找,應(yīng)該是微軟動(dòng)了什么手腳。

2)使用CORS跨域

首先介紹下CORS如何使用,在WebApiCORS項(xiàng)目上面使用Nuget搜索“microsoft.aspnet.webapi.cors”,安裝第一個(gè)

C#,WebApi,CORS,跨域

然后在App_Start文件夾下面的WebApiConfig.cs文件夾配置跨域

public static class WebApiConfig  {    public static void Register(HttpConfiguration config)    {      //跨域配置      config.EnableCors(new EnableCorsAttribute("*", "*", "*"));      // Web API 路由      config.MapHttpAttributeRoutes();      config.Routes.MapHttpRoute(        name: "DefaultApi",        routeTemplate: "api/{controller}/{action}/{id}",        defaults: new { id = RouteParameter.Optional }      );    }  }

我們暫定三個(gè)“*”號(hào),當(dāng)然,在項(xiàng)目中使用的時(shí)候一般需要指定對(duì)哪個(gè)域名可以跨域、跨域的操作有哪些等等。這個(gè)在下面介紹。

IE10、IE11

C#,WebApi,CORS,跨域

谷歌瀏覽器

C#,WebApi,CORS,跨域

IE8、IE9

C#,WebApi,CORS,跨域

這個(gè)時(shí)候又有新問(wèn)題了,怎么回事呢?我都已經(jīng)設(shè)置跨域了呀,怎么IE8、9還是不行呢?這個(gè)時(shí)候就有必要說(shuō)說(shuō)CORS的瀏覽器支持問(wèn)題了。網(wǎng)上到處都能搜到這張圖:

C#,WebApi,CORS,跨域

上圖描述了CORS的瀏覽器支持情況,可以看到IE8、9是部分支持的。網(wǎng)上說(shuō)的解決方案都是Internet Explorer 8、9使用 XDomainRequest對(duì)象實(shí)現(xiàn)CORS。是不是有這么復(fù)雜?于是博主各種百度尋找解決方案。最后發(fā)現(xiàn)在調(diào)用處指定jQuery.support.cors = true;這一句就能解決IE8、9的問(wèn)題了。具體是在Index.js里面

jQuery.support.cors = true;var ApiUrl = "http://localhost:27221/";$(function () {  $.ajax({    type: "get",    url: ApiUrl + "api/Charging/GetAllChargingData",    data: {},    success: function (data, status) {      if (status == "success") {        $("#div_test").html(data);      }    },    error: function (e) {      $("#div_test").html("Error");    },    complete: function () {    }  });});

這句話(huà)的意思就是指定瀏覽器支持跨域。原來(lái)IE9以上版本的瀏覽器、谷歌、火狐等都默認(rèn)支持跨域,而IE8、9卻默認(rèn)不支持跨域,需要我們指定一下。你可以在你的瀏覽器里面打印jQuery.support.cors看看。這樣設(shè)置之后是否能解決問(wèn)題呢?我們來(lái)看效果:

C#,WebApi,CORS,跨域

問(wèn)題完美解決。至于網(wǎng)上說(shuō)的CORS對(duì)IE8、9的解決方案XDomainRequest是怎么回事,有待實(shí)例驗(yàn)證。

3)CORS的具體參數(shù)設(shè)置。

上文我們使用

config.EnableCors(new EnableCorsAttribute("*", "*", "*"));

這一句解決了跨域問(wèn)題,上面說(shuō)了,這種*號(hào)是不安全的。因?yàn)樗硎局灰獎(jiǎng)e人知道了你的請(qǐng)求url,任何請(qǐng)求都可以訪(fǎng)問(wèn)到你的資源。這是相當(dāng)危險(xiǎn)的。所以需要我們做一些配置,限制訪(fǎng)問(wèn)權(quán)限。比如我們比較常見(jiàn)的做法如下:

配置方法一、在Web.Config里面

C#,WebApi,CORS,跨域

然后在WebApiConfig.cs文件的Register方法里面

C#,WebApi,CORS,跨域

配置方法二、如果你只想對(duì)某一些api做跨域,可以直接在API的類(lèi)上面使用特性標(biāo)注即可。

[EnableCors(origins: "http://localhost:8081/", headers: "*", methods: "GET,POST,PUT,DELETE")]  public class ChargingController : ApiController  {    /// <summary>    /// 得到所有數(shù)據(jù)    /// </summary>    /// <returns>返回?cái)?shù)據(jù)</returns>    [HttpGet]    public string GetAllChargingData()    {      return "Success";    }  }

四、總結(jié)

以上就是一個(gè)簡(jiǎn)單的CORS解決WebApi跨域問(wèn)題的實(shí)例,由于博主使用WebApi的時(shí)間并不長(zhǎng),所以很多理論觀點(diǎn)未必成熟,如果有說(shuō)的不對(duì)的,歡迎指出。也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到c#教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 鸡东县| 都昌县| 平安县| 海门市| 翁牛特旗| 固始县| 南康市| 洱源县| 桐城市| 米林县| 锡林浩特市| 双流县| 栾城县| 永定县| 修文县| 巴马| 邢台县| 阜南县| 茌平县| 泗水县| 宁都县| 定兴县| 普格县| 合山市| 永城市| 长岭县| 琼中| 区。| 谷城县| 太仓市| 安仁县| 抚松县| 敦煌市| 东阿县| 海丰县| 庆城县| 安陆市| 静乐县| 遂宁市| 铁岭县| 陈巴尔虎旗|