溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C# WebApi CORS跨域問題解決方案

發(fā)布時間:2020-10-07 17:02:22 來源:腳本之家 閱讀:131 作者:懶得安分 欄目:編程語言

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

一、跨域問題的由來

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

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

二、跨域問題解決原理

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

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

下面我就結(jié)合一個簡單的實(shí)例來說明下如何使用CORS解決WebApi的跨域問題。

1、場景描述

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

C# WebApi CORS跨域問題解決方案

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

簡單介紹下測試代碼,Web里面有一個HomeController

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

對應(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>
  測試結(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)目里面有一個測試的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ī)則為通過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、場景測試

1)我們不做任何的處理,直接將兩個項(xiàng)目運(yùn)行起來??葱Ч绾?/p>

IE瀏覽器:

C# WebApi CORS跨域問題解決方案

谷歌瀏覽器:

C# WebApi CORS跨域問題解決方案

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

2)使用CORS跨域

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

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 }
      );
    }
  }

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

IE10、IE11

C# WebApi CORS跨域問題解決方案

谷歌瀏覽器

C# WebApi CORS跨域問題解決方案

IE8、IE9

C# WebApi CORS跨域問題解決方案

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

C# WebApi CORS跨域問題解決方案

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

    }
  });
});

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

C# WebApi CORS跨域問題解決方案

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

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

上文我們使用

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

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

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

C# WebApi CORS跨域問題解決方案

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

C# WebApi CORS跨域問題解決方案

配置方法二、如果你只想對某一些api做跨域,可以直接在API的類上面使用特性標(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é)

以上就是一個簡單的CORS解決WebApi跨域問題的實(shí)例,由于博主使用WebApi的時間并不長,所以很多理論觀點(diǎn)未必成熟,如果有說的不對的,歡迎指出。也希望大家多多支持億速云。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI