日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達者為師

網(wǎng)站首頁 編程語言 正文

ASP.NET中Web?API解決跨域問題_實用技巧

作者:.NET開發(fā)菜鳥 ? 更新時間: 2022-05-08 編程語言

一、什么是跨域問題

跨域:指的是瀏覽器不能執(zhí)行其他網(wǎng)站的腳本。是由瀏覽器的同源策略造成的,是瀏覽器施加的安全限制。(服務(wù)端可以正常接收瀏覽器發(fā)生的請求,也可以正常返回,但是由于瀏覽器的安全策略,瀏覽器不能處理服務(wù)端的返回)。

那么什么是同源策略呢?

同源策略/SOP(Same origin policy)是一種約定,由Netscape公司1995年引入瀏覽器,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,瀏覽器很容易受到XSS、CSFR等攻擊。所謂同源是指"協(xié)議+域名+端口"三者相同,即便兩個不同的域名指向同一個ip地址,也非同源。

正是由于這個原因,如果是在不同的項目之間進行調(diào)用(這里說的調(diào)用指的是瀏覽器調(diào)用后端,如果是后端直接調(diào)用就不會存在跨域問題)就會被瀏覽器阻止。WebApi中常見的場景:Web Api作為單獨的數(shù)據(jù)服務(wù)層,提供接口供前端界面調(diào)用,MVC項目作為顯示層,這種情況下如果在MVC的前端界面里面通過ajax調(diào)用WebApi的接口,就會存在跨域問題。

二、如何解決跨域問題

網(wǎng)上有很多跨域問題的解決方案,這里就不在一一列舉了,下面主要講解一下在WebApi中如何使用CORS解決跨域問題。CORS全稱Cross-Origin Resource Sharing,中文全稱是跨域資源共享。CORS解決跨域問題的原理是在http的請求報文和響應(yīng)報文里面加入響應(yīng)的標識告訴瀏覽器能夠訪問哪些域名的請求。

三、使用代碼解決跨域問題

下面結(jié)合一個具體的實例來講解在WebApi里面如何使用CORS解決跨域問題。

1、場景描述

新建兩個單獨的項目:一個WebApi項目(帶有MVC功能,用來提供數(shù)據(jù)和頁面顯示),一個MVC項目(只是負責頁面顯示),項目結(jié)構(gòu)如下圖所示:

其中,WebApi項目的端口號是:33982,MVC項目的端口號是:34352(這兩個端口號是在本機的地址,在其他電腦上端口號可能不同)。顯而易見:兩個項目的端口號不同,不屬于同源,如果在MVC里面通過前端調(diào)用WebApi提供的數(shù)據(jù)接口,就會出現(xiàn)跨域的問題。

2、項目結(jié)構(gòu)

2.1 WebApi項目結(jié)構(gòu)

新建WebApiController文件夾,用來存放WebApi控制器,并新建一個WebApi控制器,命名為Student。StudentController控制器的代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebApi.Entity;

namespace WebApi.WebApiController
{
    public class StudentController : ApiController
    {
        public static List studentList = InitStudentList();

        private static List InitStudentList()
        {
            return new List()
            {
               new Student {StudentID =1,StudentName="唐僧",Age=24,Sex="男",Major="師范"},
               new Student {StudentID =2,StudentName="孫悟空",Age=579,Sex="男",Major="管理"},
               new Student {StudentID =3,StudentName="沙悟凈",Age=879,Sex="男",Major="水利工程"},
               new Student {StudentID =4,StudentName="白骨精",Age=456,Sex="女",Major="表演"},
               new Student {StudentID =5,StudentName="玉兔精",Age=456,Sex="女",Major="舞蹈"}
            };
        }

        [HttpGet]
        public IHttpActionResult GetAllStudent()
        {
            return Json>(studentList);
        }
    }
}

修改WebApi配置文件類,路由規(guī)則里面增加action,代碼如下:

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

namespace WebApi
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API 配置和服務(wù)

            // Web API 路由
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

新建一個MVC控制器,命名為Student,并添加Index視圖,Index視圖代碼如下:

@{
    Layout = null;
}





    
    測試跨域問題
    


    
Get Student List

2.2 MVC項目結(jié)構(gòu)

MVC項目結(jié)構(gòu)比較簡單,新建一個名為Student的控制器,并添加視圖,視圖如下:

@{
    Layout = null;
}





    
    測試跨域問題
    


    
Get Student List

四、測試

1、在不做任何處理情況下的測試

先看看同源下的訪問情況,直接啟動WebApi項目,截圖如下:

點擊按鈕,測試結(jié)果如下:

因為是在同一個域中,所以訪問沒有問題,前端可以正常獲取到WebApi返回的數(shù)據(jù)。下面在來看看在MVC項目中的測試情況。測試截圖如下:

從圖中可以看出訪問失敗了,按F12查看訪問情況:

從上面的截圖中可以看出,發(fā)生了跨域訪問,瀏覽器出于安全性的考慮,不能接收返回的數(shù)據(jù)。

五、使用CORS解決跨域問題

1、安裝CORS

在WebApi項目上右鍵->管理NuGet程序包,然后搜索“microsoft.aspnet.webapi.cors”,選擇第一個進行安裝

具體的安裝過程在這里不再詳細解釋。

2、配置跨域

在WebApiConfig.cs類中配置跨域,修改后的代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.Http.Cors;

namespace WebApi
{
    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 }
            );
        }
    }
}

這里使用“*”號表示對所有的域名都可以跨域。再次從MVC里面訪問WebApi,查看測試結(jié)果:

從上面的截圖中可以看出,這時就可以允許跨域訪問了,在Response Headers里面添加了:Access-Control-Allow-Origin:*。

六、CORS參數(shù)詳解

在上面我們在WebApi的配置文件中使用了:

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

?這一句代碼解決了跨域問題。但是這種“*”號是不安全的。查看MSDN,發(fā)現(xiàn)EnableCorsAttribute類有如下的構(gòu)造函數(shù):

public EnableCorsAttribute(
    string origins,
    string headers,
    string methods
)

詳細的參數(shù)解釋請查看MSDN。

知道了EnableCorsAttribute類的構(gòu)造函數(shù)以后,我們可以使用下面的方法進行改進。

方法一:在Web.Config文件的appSettings節(jié)點里面配置參數(shù):

然后修改WebApiConfig.cs文件的Register方法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.Http.Cors;
using System.Configuration;

namespace WebApi
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            #region 跨域配置
            string allowedOrigin = ConfigurationManager.AppSettings["allowedOrigin"];
            string allowedHeaders = ConfigurationManager.AppSettings["allowedHeaders"];
            string allowedMethods = ConfigurationManager.AppSettings["allowedMethods"];
            config.EnableCors(new EnableCorsAttribute(allowedOrigin, allowedHeaders, allowedMethods)); 
            #endregion
            // Web API 路由
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

方法二:如果只想對某些api或者api里面的某些方法做跨域,可以直接在API控制器類上面使用特性標注或者在方法上面使用特性標注。

允許Student控制器可以跨域:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebApi.Entity;
using System.Web.Http.Cors;

namespace WebApi.WebApiController
{
    [EnableCors(origins:"http://localhost:34352",headers:"*",methods:"GET,POST,PUT,DELETE")]
    public class StudentController : ApiController
    {
        public static List studentList = InitStudentList();

        private static List InitStudentList()
        {
            return new List()
            {
             new Student {StudentID =1,StudentName="唐僧",Age=24,Sex="男",Major="師范"},
                new Student {StudentID =2,StudentName="孫悟空",Age=579,Sex="男",Major="管理"},
               new Student {StudentID =3,StudentName="沙悟凈",Age=879,Sex="男",Major="水利工程"},
               new Student {StudentID =4,StudentName="白骨精",Age=456,Sex="女",Major="表演"},
               new Student {StudentID =5,StudentName="玉兔精",Age=456,Sex="女",Major="舞蹈"}
            };
        }

        [HttpGet]
        public IHttpActionResult GetAllStudent()
        {
            return Json>(studentList);
        }
    }
}

只允許Student控制器里面的GetAllStudent方法可以跨域:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebApi.Entity;
using System.Web.Http.Cors;

namespace WebApi.WebApiController
{

    public class StudentController : ApiController
    {
        public static List studentList = InitStudentList();

        private static List InitStudentList()
        {
            return new List()
            {
             new Student {StudentID =1,StudentName="唐僧",Age=24,Sex="男",Major="師范"},
                new Student {StudentID =2,StudentName="孫悟空",Age=579,Sex="男",Major="管理"},
               new Student {StudentID =3,StudentName="沙悟凈",Age=879,Sex="男",Major="水利工程"},
               new Student {StudentID =4,StudentName="白骨精",Age=456,Sex="女",Major="表演"},
               new Student {StudentID =5,StudentName="玉兔精",Age=456,Sex="女",Major="舞蹈"}
            };
        }

        /// 
        /// 允許跨域
        /// 
        /// 
        [EnableCors(origins: "http://localhost:34352", headers: "*", methods: "GET,POST,PUT,DELETE")]
        [HttpGet]
        public IHttpActionResult GetAllStudent()
        {
            return Json>(studentList);
        }

        /// 
        /// 不允許跨域
        /// 
        [HttpPost]
        public void Post()
        { }
    }
}

原文鏈接:https://www.cnblogs.com/dotnet261010/p/8831450.html

欄目分類
最近更新