欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

ASP.NET中Web API解決跨域問(wèn)題

 更新時(shí)間:2022年03月08日 10:31:51   作者:.NET開發(fā)菜鳥  
這篇文章介紹了ASP.NET中Web API解決跨域問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

一、什么是跨域問(wèn)題

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

那么什么是同源策略呢?

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

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

二、如何解決跨域問(wèn)題

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

三、使用代碼解決跨域問(wèn)題

下面結(jié)合一個(gè)具體的實(shí)例來(lái)講解在WebApi里面如何使用CORS解決跨域問(wèn)題。

1、場(chǎng)景描述

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

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

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

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

新建WebApiController文件夾,用來(lái)存放WebApi控制器,并新建一個(gè)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<Student> studentList = InitStudentList();

        private static List<Student> InitStudentList()
        {
            return new List<Student>()
            {
               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<List<Student>>(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 }
            );
        }
    }
}

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

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>測(cè)試跨域問(wèn)題</title>
    <script src="~/Scripts/jquery-1.10.2.min.js" type="text/javascript"></script>
</head>
<body>
    <div style="background-color:#008000;padding:10px;margin:5px;">
        <div style="font-weight:bold;margin-bottom:5px;">Get Student List</div>
        <div style="padding-bottom:5px;">
            <input id="btnGetStudentList" name="btnGetStudentList" type="button" value="Get Student List" />
        </div>
        <div id="students"></div>
    </div>
    <script>
        $('#btnGetStudentList').click(function () {
            $.ajax({
                url: '/api/Student/GetAllStudent',
                type: 'GET',
                dataType: 'json'
            }).success(function (result) {
                DisplayStudentList(result);
            }).error(function (data) {
                alert(data);
            });
        });
        function DisplayStudentList(result) {
            var studentTable = $("<table cellpadding='3' cellspacing='3'></table>");
            var studentTableTitle = $("<tr><th>StudentID</th><th>StudentName</th><th>Age</th><th>Sex</th><th>Major</th></tr>");
            studentTableTitle.appendTo(studentTable);

            for (var i = 0; i < result.length; i++) {
                var studentTableContent = $("<tr><td>"
                    + result[i].StudentID + "</td><td>"
                    + result[i].StudentName + "</td><td>"
                    + result[i].Age + "</td><td>"
                    + result[i].Sex + "</td><td>"
                    + result[i].Major + "</td></tr>"
                );
                studentTableContent.appendTo(studentTable);
            }

            $('#students').html(studentTable);
        }
    </script>
</body>
</html>

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

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

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>測(cè)試跨域問(wèn)題</title>
    <script src="~/Scripts/jquery-1.10.2.min.js" type="text/javascript"></script>
</head>
<body>
    <div style="background-color:#008000;padding:10px;margin:5px;">
        <div style="font-weight:bold;margin-bottom:5px;">Get Student List</div>
        <div style="padding-bottom:5px;">
            <input id="btnGetStudentList" name="btnGetStudentList" type="button" value="Get Student List" />
        </div>
        <div id="students"></div>
    </div>
    <script>
        $('#btnGetStudentList').click(function () {
            $.ajax({
                url: 'http://localhost:33982//api/Student/GetAllStudent',
                type: 'GET',
                dataType: 'json'
            }).success(function (result) {
                DisplayStudentList(result);
            }).error(function (data) {
                alert("失敗");
            });
        });
        function DisplayStudentList(result) {
            var studentTable = $("<table cellpadding='3' cellspacing='3'></table>");
            var studentTableTitle = $("<tr><th>StudentID</th><th>StudentName</th><th>Age</th><th>Sex</th><th>Major</th></tr>");
            studentTableTitle.appendTo(studentTable);

            for (var i = 0; i < result.length; i++) {
                var studentTableContent = $("<tr><td>"
                    + result[i].StudentID + "</td><td>"
                    + result[i].StudentName + "</td><td>"
                    + result[i].Age + "</td><td>"
                    + result[i].Sex + "</td><td>"
                    + result[i].Major + "</td></tr>"
                );
                studentTableContent.appendTo(studentTable);
            }

            $('#students').html(studentTable);
        }
    </script>
</body>
</html>

四、測(cè)試

1、在不做任何處理情況下的測(cè)試

先看看同源下的訪問(wèn)情況,直接啟動(dòng)WebApi項(xiàng)目,截圖如下:

點(diǎn)擊按鈕,測(cè)試結(jié)果如下:

因?yàn)槭窃谕粋€(gè)域中,所以訪問(wèn)沒(méi)有問(wèn)題,前端可以正常獲取到WebApi返回的數(shù)據(jù)。下面在來(lái)看看在MVC項(xiàng)目中的測(cè)試情況。測(cè)試截圖如下:

從圖中可以看出訪問(wèn)失敗了,按F12查看訪問(wèn)情況:

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

五、使用CORS解決跨域問(wèn)題

1、安裝CORS

在WebApi項(xiàng)目上右鍵->管理NuGet程序包,然后搜索“microsoft.aspnet.webapi.cors”,選擇第一個(gè)進(jìn)行安裝

具體的安裝過(guò)程在這里不再詳細(xì)解釋。

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

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

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

六、CORS參數(shù)詳解

在上面我們?cè)赪ebApi的配置文件中使用了:

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

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

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

詳細(xì)的參數(shù)解釋請(qǐng)查看MSDN。

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

方法一:在Web.Config文件的appSettings節(jié)點(diǎn)里面配置參數(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 }
            );
        }
    }
}

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

允許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<Student> studentList = InitStudentList();

        private static List<Student> InitStudentList()
        {
            return new List<Student>()
            {
             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<List<Student>>(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<Student> studentList = InitStudentList();

        private static List<Student> InitStudentList()
        {
            return new List<Student>()
            {
             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="舞蹈"}
            };
        }

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

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

到此這篇關(guān)于ASP.NET中Web API解決跨域問(wèn)題的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論