如何配置ASP.NET WebAPI以优雅地解决所有跨域资源共享问题?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1833个文字,预计阅读时间需要8分钟。
一、什么是跨域问题?跨域:指的是浏览器不能执行跨源脚本。简单来说,就是浏览器出于安全考虑,禁止一个域下的文档或脚本去请求另一个域下的资源。
二、跨域问题表现:
1.浏览器不能执行跨源脚本的请求。
2.浏览器会拦截跨域请求,无法获取到响应数据。
三、原因:
1.浏览器出于安全考虑,防止恶意脚本窃取数据。
2.浏览器的同源策略,即协议、域名、端口三者一致。
四、解决方法:
1.服务器设置CORS(跨源资源共享)头部。
2.使用JSONP技术。
3.使用代理服务器。
4.前后端分离,使用WebSocket等。
一、什么是跨域问题
跨域:指的是浏览器不能执行其他网站的脚本。是由浏览器的同源策略造成的,是浏览器施加的安全限制。(服务端可以正常接收浏览器发生的请求,也可以正常返回,但是由于浏览器的安全策略,浏览器不能处理服务端的返回)。
那么什么是同源策略呢?
同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
正是由于这个原因,如果是在不同的项目之间进行调用(这里说的调用指的是浏览器调用后端,如果是后端直接调用就不会存在跨域问题)就会被浏览器阻止。WebApi中常见的场景:Web Api作为单独的数据服务层,提供接口供前端界面调用,MVC项目作为显示层,这种情况下如果在MVC的前端界面里面通过ajax调用WebApi的接口,就会存在跨域问题。
二、如何解决跨域问题
网上有很多跨域问题的解决方案,这里就不在一一列举了,下面主要讲解一下在WebApi中如何使用CORS解决跨域问题。CORS全称Cross-Origin Resource Sharing,中文全称是跨域资源共享。CORS解决跨域问题的原理是在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:"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: "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解决跨域问题的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持自由互联。
本文共计1833个文字,预计阅读时间需要8分钟。
一、什么是跨域问题?跨域:指的是浏览器不能执行跨源脚本。简单来说,就是浏览器出于安全考虑,禁止一个域下的文档或脚本去请求另一个域下的资源。
二、跨域问题表现:
1.浏览器不能执行跨源脚本的请求。
2.浏览器会拦截跨域请求,无法获取到响应数据。
三、原因:
1.浏览器出于安全考虑,防止恶意脚本窃取数据。
2.浏览器的同源策略,即协议、域名、端口三者一致。
四、解决方法:
1.服务器设置CORS(跨源资源共享)头部。
2.使用JSONP技术。
3.使用代理服务器。
4.前后端分离,使用WebSocket等。
一、什么是跨域问题
跨域:指的是浏览器不能执行其他网站的脚本。是由浏览器的同源策略造成的,是浏览器施加的安全限制。(服务端可以正常接收浏览器发生的请求,也可以正常返回,但是由于浏览器的安全策略,浏览器不能处理服务端的返回)。
那么什么是同源策略呢?
同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
正是由于这个原因,如果是在不同的项目之间进行调用(这里说的调用指的是浏览器调用后端,如果是后端直接调用就不会存在跨域问题)就会被浏览器阻止。WebApi中常见的场景:Web Api作为单独的数据服务层,提供接口供前端界面调用,MVC项目作为显示层,这种情况下如果在MVC的前端界面里面通过ajax调用WebApi的接口,就会存在跨域问题。
二、如何解决跨域问题
网上有很多跨域问题的解决方案,这里就不在一一列举了,下面主要讲解一下在WebApi中如何使用CORS解决跨域问题。CORS全称Cross-Origin Resource Sharing,中文全称是跨域资源共享。CORS解决跨域问题的原理是在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:"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: "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解决跨域问题的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持自由互联。

