ASP.NET WebAPI 15 CORS
同源策略
首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。
对于同源必须要求URL在如下几个方面相同:
- 网络协议(http与https不同)
- 域名
- 端口(80与8080不同)
JSONP
JSONP是跨域访问的一种方法。在web开发中我们经常会引用第三方的js文件,这个时候我们会发现浏览器并没有拦截。JSONP就是利用向网页中添加script标签的方式去进行跨域访问。
一般处理在处理JSONP的时候会将回调函数名与参数作为QueryString传给服务端,服务端再根据上传的函数名生成js回传给客户端。
由于采用的是添加script标签的方式,所以JSONP只能通过GET方法访问服务器。另外由于服务端要根据上传的函数名生成js,所以JSONP方法得到的并不是数据,而是方法的调用。
在Demo中我写了一个JSONP的服务端生成与客户端调用方法。
CORS
对于CORSAccess-Control-Allow-Origin
引用System.Web.Http.Cors库
通过NuGet管理添加System.Web.Http.Cors,我引用的库名为:Microsoft ASP.NET Web API 2.2 Cross-Origin Support
引用库后,首先在WebApiConfig.Register方法中首行,添加一句 config.EnableCors()(记得一定要添加到首行。开始我也是添加在末行,但一直运行不成功,花了好半天功夫,才找到是这个问题。这个以后有时间再看看Cors内部的实现原理,按说不应该出现这样的问题。)。
public static void Register(HttpConfiguration config) { // Web API 配置和服务 config.EnableCors(); // Web API 路由 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } ); }
System.Web.Http.Cors库对于Cors控制也是通过特性(Attribute)来实现的。System.Web.Http.Cors库提供了两个与Cors的特性:EnableCorsAttribute与DisableCorsAttribute,这两个特性都是基于Controller与Action的。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public sealed class DisableCorsAttribute : Attribute, ICorsPolicyProvider { public DisableCorsAttribute(); public Task<System.Web.Cors.CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken); }
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public sealed class EnableCorsAttribute : Attribute, ICorsPolicyProvider { public EnableCorsAttribute(string origins, string headers, string methods); public EnableCorsAttribute(string origins, string headers, string methods, string exposedHeaders); public IList<string> ExposedHeaders { get; } public IList<string> Headers { get; } public IList<string> Methods { get; } public IList<string> Origins { get; } public long PreflightMaxAge { get; set; } public bool SupportsCredentials { get; set; } public Task<System.Web.Cors.CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken); }
EnableCorsAttribute与DisableCorsAttribute都实现了ICorsPolicyProvider接口。但 DisableCorsAttribute没有别的属性与构造函数,它的使用场景大致为当Controller已经被添加EnableCorsAttribute后,为个别不做Cors的Action禁用掉。
EnableCorsAttribute的与响应头部信息相对应,其对应关系如下:
属性 |
头部信息 |
备注 |
Origins |
Allow-Control-Allow-Origin |
CORS允许的请求域名,用逗号(,)去区他不同的域名,如:http://localhost:64299,http://www.baidu.com。 对于没有域名,可以用星号(*) |
Methods |
Allow-Control-Allow-Method |
CORS允许的请求方法,用法同Origins |
Headers |
Allow-Control-Allow-Headers |
|
ExposedHeaders |
Allow-Control-Expose-Header |
|
PreflightMaxAge |
Allow-Control-Max-Age |
|
SupportsCredentials |
Allow-Control-Allow-Credentials |
还是IE
在测试过程中我发现在火狐上能够正常运行,但到了IE是就不行了,经过一番查找,发现要在要添加一句话:
jQuery.support.cors = true;
但加了这句话后,虽然/api/demo/GetFigureByCors可以调的,但/api/demo/GetFigureNoCors也可以调用了。到这又郁闷了,这又是要搞那样。又经过一番折腾,才发现这个时候jQuery并不是用的XMLHttpRequest,而是采用的IE自带的XDomainRequest组件,并且该组件只支持IE8及以上。
关于Demo
在Demo中出于对同源的规则的考虑,我定义了两个Web项目:API_15与API_15.Web。API_15中的DemoController分别定义的三个方法GetFigureByJsonP,GetFigureNoCors,GetFigureByCors分别用于JSONP,非Cors,Cors调用。
public class DemoController : ApiController { public HttpResponseMessage GetFigureByJsonP(string callback) { StringBuilder result = new StringBuilder(); result.Append("callback("); result.Append(JsonConvert.SerializeObject(FigureManager.Figures)); result.Append(")"); return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(result.ToString()) }; } public IEnumerable<Figure> GetFigureNoCors() { return FigureManager.Figures; } //[EnableCors(origins:"*",headers: "*",methods:"*")] [EnableCors(origins: "http://localhost:64299,http://www.baidu.com", headers: "GET,POST", methods: "*")] public IEnumerable<Figure> GetFigureByCors() { return FigureManager.Figures; } }
在API_15.Web项目中只定义了一个页面,通过jQuery的AJAX去调用API_15中三个Action。
源码
Github: https://github.com/BarlowDu/WebAPI(API_15,API_15.Web)
ASP.NET WebAPI 15 CORS的更多相关文章
- WebAPI 15 CORS
WebAPI 15 CORS 同源策略 首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 对于同源必须要求URL在如下几个方 ...
- Asp.Net WebApi 启用CORS跨域访问指定多个域名
1.后台action指定 EnableCors指定可访问的域名多个,使用逗号隔开 //支持客户端凭据提交,指定多个域名,使用逗号隔开 [EnableCors("http://localhos ...
- Asp.Net WebApi+Microsoft.AspNet.WebApi.Core 启用CORS跨域访问
WebApi中启用CORS跨域访问 1.安装 Nugget包Microsoft.AspNet.WebApi.Cors This package contains the components to e ...
- Asp.Net WebApi 项目及依赖整理
一.目前版本 Microsoft ASP.NET Web API 2.2 对应程序集版本5.2.3 二.默认生成的配置文件中的内容 <packages> <package id=&q ...
- 连表查询都用Left Join吧 以Windows服务方式运行.NET Core程序 HTTP和HTTPS的区别 ASP.NET SignalR介绍 asp.net—WebApi跨域 asp.net—自定义轻量级ORM C#之23中设计模式
连表查询都用Left Join吧 最近看同事的代码,SQL连表查询的时候很多时候用的是Inner Join,而我觉得对我们的业务而言,99.9%都应该使用Left Join(还有0.1%我不知道在 ...
- Enable Cross-Origin Requests in Asp.Net WebApi 2[Reprint]
Browser security prevents a web page from making AJAX requests to another domain. This restriction i ...
- 为Asp.net WebApi 添加跨域支持
Nuget安装包:microsoft.aspnet.webapi.cors 原文地址:https://www.asp.net/web-api/overview/security/enabling-cr ...
- 【开源】分享一个前后端分离方案-前端angularjs+requirejs+dhtmlx 后端asp.net webapi
一.前言 半年前左右折腾了一个前后端分离的架子,这几天才想起来翻出来分享给大家.关于前后端分离这个话题大家也谈了很久了,希望我这个实践能对大家有点点帮助,演示和源码都贴在后面. 二.技术架构 这两年a ...
- ASP.NET WebAPI 08 Message,HttpConfiguration,DependencyResolver
ASP.NET WebAPI 08 Message,HttpConfiguration,DependencyResolver Message WebAPI作为通信架构必定包含包含请求与响应两个方法 ...
随机推荐
- Android开发(51) 摄像头自动对焦。在OpenCV图像识别中连续拍照时自动对焦和拍照。
概述 对焦,这里所说的“焦”是指“焦距”.在拍照时,一定是需要调焦的.一般会在目标位置最清晰的时候会停止对焦.最近在处理OpenCV进行图像识别时,需要连续的调焦(对焦),并在对焦完成后进行拍照,获取 ...
- Activity跳转时生命周期跟踪
1. 步骤1(打开First Activity):经过onCreate.onStart.onResume后First Activity就展现啦: 2. 步骤2(跳转至Second Activity): ...
- 现代JavaScript开发者的工具箱
自从HTML5变得流行以来,整个Web平台取得了长足的进步,人们也开始将JavaScript视为一门能够创建复杂应用的语言.许多新的API纷纷浮现,而关于浏览器如何应用这些技术的文章也大量涌现. 作为 ...
- 泊松回归(Poisson Regression)
本博客已经迁往http://www.kemaswill.com/, 博客园这边也会继续更新, 欢迎关注~ Linear Regression预测的目标\(Y\)是连续值, Logistic Regre ...
- 重构第2天:方法搬移(Move Method)
现在就重构来说是非常普通的,虽然我们经常会漏掉或忽略一些需要重构的地方.方法搬移,正如所定义的那样,把方法搬移到更适合他的位置.让我们看看下面这一段重构前的代码: 理解:方法搬移,正如所定义的那样,把 ...
- [转]YII2 常用数据库操作
1.对象操作: //1.简单查询 $admin=Admin::model()->findAll($condition,$params); $admin=Admin::model()->fi ...
- java nio 网络框架实现
maven项目 https://github.com/solq360/common 链式编/解码 链路层链式处理 管道管理socket 多协议处理非常方便 仿netty NioEventLoop 单线 ...
- HTML注释引起的问题
因为规范要求需要对页面进行说明,添加作者等信息,所以在cshtml的代码中添加了html注释,包括之前使用jsp也是这样做的: 在页面布局的时候,需要对高度进行动态计算,IE8以上没有问题,主要是在I ...
- Shader的语法
Shader "name" { [Properties] Subshaders [Fallback] }(1)Properties:{ Property [Property ... ...
- STL中stack小结
(1)为了运用stack,你必须包含头文件<stack>:#include<stack> (2)在头文件中stack定义如下: namespace std{ template ...