返回顶部
首页 > 资讯 > 后端开发 > ASP.NET >ASP.NET中WebAPI解决跨域问题
  • 349
分享到

ASP.NET中WebAPI解决跨域问题

2024-04-02 19:04:59 349人浏览 八月长安
摘要

一、什么是跨域问题 跨域:指的是浏览器不能执行其他网站的脚本。是由浏览器的同源策略造成的,是浏览器施加的安全限制。(服务端可以正常接收浏览器发生的请求,也可以正常返回,但是由于浏览器

一、什么是跨域问题

跨域:指的是浏览器不能执行其他网站的脚本。是由浏览器的同源策略造成的,是浏览器施加的安全限制。(服务端可以正常接收浏览器发生的请求,也可以正常返回,但是由于浏览器的安全策略,浏览器不能处理服务端的返回)。

那么什么是同源策略呢?

同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。

正是由于这个原因,如果是在不同的项目之间进行调用(这里说的调用指的是浏览器调用后端,如果是后端直接调用就不会存在跨域问题)就会被浏览器阻止。webapi中常见的场景:WEB api作为单独的数据服务层,提供接口供前端界面调用,mvc项目作为显示层,这种情况下如果在MVC的前端界面里面通过ajax调用WebApi的接口,就会存在跨域问题。

二、如何解决跨域问题

网上有很多跨域问题的解决方案,这里就不在一一列举了,下面主要讲解一下在WebApi中如何使用CORS解决跨域问题。CORS全称Cross-Origin Resource Sharing,中文全称是跨域资源共享。CORS解决跨域问题的原理是在Http的请求报文和响应报文里面加入响应的标识告诉浏览器能够访问哪些域名的请求。

三、使用代码解决跨域问题

下面结合一个具体的实例来讲解在WebApi里面如何使用CORS解决跨域问题。

1、场景描述

新建两个单独的项目:一个WebApi项目(带有MVC功能,用来提供数据和页面显示),一个MVC项目(只是负责页面显示),项目结构如下图所示:

其中,WebApi项目的端口号是:33982,MVC项目的端口号是:34352(这两个端口号是在本机的地址,在其他电脑上端口号可能不同)。显而易见:两个项目的端口号不同,不属于同源,如果在MVC里面通过前端调用WebApi提供的数据接口,就会出现跨域的问题。

2、项目结构

2.1 WebApi项目结构

新建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<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配置文件类,路由规则里面增加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 配置和服务

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

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>测试跨域问题</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项目结构

MVC项目结构比较简单,新建一个名为Student的控制器,并添加视图,视图如下:

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>测试跨域问题</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>

四、测试

1、在不做任何处理情况下的测试

先看看同源下的访问情况,直接启动WebApi项目,截图如下:

点击按钮,测试结果如下:

因为是在同一个域中,所以访问没有问题,前端可以正常获取到WebApi返回的数据。下面在来看看在MVC项目中的测试情况。测试截图如下:

从图中可以看出访问失败了,按F12查看访问情况:

从上面的截图中可以看出,发生了跨域访问,浏览器出于安全性的考虑,不能接收返回的数据。

五、使用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,查看测试结果:

从上面的截图中可以看出,这时就可以允许跨域访问了,在Response Headers里面添加了:Access-Control-Allow-Origin:*。

六、CORS参数详解

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

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

 这一句代码解决了跨域问题。但是这种“*”号是不安全的。查看MSDN,发现EnableCorsAttribute类有如下的构造函数:

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

详细的参数解释请查看MSDN。

知道了EnableCorsAttribute类的构造函数以后,我们可以使用下面的方法进行改进。

方法一:在Web.Config文件的appSettings节点里面配置参数:

然后修改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<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()
        { }
    }
}

到此这篇关于asp.net中Web API解决跨域问题的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: ASP.NET中WebAPI解决跨域问题

本文链接: https://lsjlt.com/news/141721.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • ASP.NET中WebAPI解决跨域问题
    一、什么是跨域问题 跨域:指的是浏览器不能执行其他网站的脚本。是由浏览器的同源策略造成的,是浏览器施加的安全限制。(服务端可以正常接收浏览器发生的请求,也可以正常返回,但是由于浏览器...
    99+
    2024-04-02
  • Nginx解决跨域问题
    目录 前言 一、跨域问题 1.什么是跨域  2.CORS 二、Nginx跨域处理 三.补充 前言 这几天出现了一个问题,我们中的一个A系统需要给B系统调用,造成了跨域问题。 一、跨域问题 1.什么是跨域 当一个请求url的协议、域...
    99+
    2023-09-02
    nginx 服务器 开发语言
  • node.js中如何解决跨域问题
    这篇文章主要讲解了“node.js中如何解决跨域问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“node.js中如何解决跨域问题”吧!如果用Express框架的话可以使用cors包来解决跨...
    99+
    2023-06-17
  • 解决Django cors跨域问题
    Django cors跨域问题 前后端分离项目中的跨域问题 即同源策略 同源策略:同源策略/SOP(Same origin policy)是一种约定,由 Netscape 公司 19...
    99+
    2024-04-02
  • Nginx怎么解决WebApi跨域二次请求及Vue单页面的问题
    今天小编给大家分享一下Nginx怎么解决WebApi跨域二次请求及Vue单页面的问题的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文...
    99+
    2024-04-02
  • vue-cli3 中怎么解决跨域问题
    这篇文章给大家介绍vue-cli3 中怎么解决跨域问题,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1:将任何未知请求转发到代理服务器如:前端地址:127.0.0.1后端地址:127....
    99+
    2024-04-02
  • vue中axios如何解决跨域问题
    这篇文章主要介绍vue中axios如何解决跨域问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!vue中axios不支持vue.use()方式声明使用。 所以有两种方法可以解决这点:...
    99+
    2024-04-02
  • web中如何解决跨域的问题
    这篇文章主要为大家展示了“web中如何解决跨域的问题”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“web中如何解决跨域的问题”这篇文章吧。什么是跨域?概念如下:只要协议、域名、端口有任何一个不同...
    99+
    2023-06-08
  • SpringBoot中的跨域问题怎么解决
    本篇内容主要讲解“SpringBoot中的跨域问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SpringBoot中的跨域问题怎么解决”吧!1、跨域访问报错当一个请求url的协议、域名...
    99+
    2023-06-29
  • Node中解决接口跨域问题详解
    目录前言CORSCORS 响应头部 - Access-Control-Allow-OriginCORS 响应头部 - Access-Control-Allow-HeadersCORS...
    99+
    2023-05-17
    Node cors解决接口跨域 Node 接口跨域
  • 解决Vue+SpringBoot+Shiro跨域问题
    目录一、配置Vue前端1、开发跨域配置2、生产跨域配置二、配置spring boot相信大家刚开始做都会遇到这个问题,在网上找了好多也不管用,都写的不全, 在这里记录一下,希望对大家...
    99+
    2024-04-02
  • javascript怎么解决跨域问题
    这篇文章主要介绍了javascript怎么解决跨域问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。javascript 跨域问题以及解决办...
    99+
    2024-04-02
  • vue2.0跨域问题怎么解决
    本篇内容主要讲解“vue2.0跨域问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue2.0跨域问题怎么解决”吧! 一种解决方案: 一般的情况下...
    99+
    2024-04-02
  • 怎么解决ajax跨域问题
    本篇内容主要讲解“怎么解决ajax跨域问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么解决ajax跨域问题”吧!什么是ajax跨域ajax跨域的原理aja...
    99+
    2024-04-02
  • ajax如何解决跨域问题
    小编给大家分享一下ajax如何解决跨域问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!跨域同源策略限制同源策略阻止从一个域上加...
    99+
    2024-04-02
  • 怎么解决WebSocket跨域问题
    怎么解决WebSocket跨域问题?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。WebSocket通信是点对点:一是建立WebSocket链接的URL加上时间戳保证通信会话是唯...
    99+
    2023-06-09
  • Ajax跨域问题如何解决
    这期内容当中小编将会给大家带来有关Ajax跨域问题如何解决,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。跨域跨域有三个条件,满足任何一个条件就是跨域 1:服务器端口不一致 2:协议不一...
    99+
    2023-06-08
  • django跨域问题如何解决
    Django跨域问题可以通过以下几种方法来解决:1. 使用Django的CORS插件:可以通过安装django-cors-heade...
    99+
    2023-09-26
    Django
  • 怎么解决SpringBoot跨域问题
    这篇文章给大家分享的是有关怎么解决SpringBoot跨域问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。允许全部请求跨域许可的代码需要继承WebMvcConfigurerAdapter类。@Configura...
    99+
    2023-06-28
  • JavaScript跨域问题怎么解决
    这篇文章主要介绍了JavaScript跨域问题怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JavaScript跨域问题怎么解决文章都会有所收获,下面我们一起来看看吧。1.什么是跨域我们常常会在页面上使...
    99+
    2023-06-27
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作