WebAPI 15 CORS
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内部的实现原理,按说不应该出现这样的问题。)。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
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的。
|
1
2
3
4
5
6
7
8
9
10
11
|
[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); } |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
[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调用。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
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)
WebAPI 15 CORS的更多相关文章
- ASP.NET WebAPI 15 CORS
同源策略 首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 对于同源必须要求URL在如下几个方面相同: 网络协议(http与 ...
- WebApi开启CORS支持跨域POST
概念:CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing).它允许浏览器向跨源服务器,发出XMLHttpRequest请求 ...
- Asp.Net WebApi 启用CORS跨域访问指定多个域名
1.后台action指定 EnableCors指定可访问的域名多个,使用逗号隔开 //支持客户端凭据提交,指定多个域名,使用逗号隔开 [EnableCors("http://localhos ...
- WebApi使用cors配置跨域问题
1.首先安装CORS,在WebApiCors项目上面使用Nuget搜索“microsoft.aspnet.webapi.cors”,安装第一个 2.当我们安装这个包之后,现有的packages目录下会 ...
- 让webapi支持CORS,可以跨域访问
1.在NuGet里搜索webapi找到下面的扩展,添加进项目里. 2.在Global.asax中添加一行代码 protected void Application_Start() { //添加CORS ...
- webapi的cors配置
NuGet搜索 cors,安装如图显示的: 一.全局配置 在App_Start文件夹的WebApiConfig.cs中加入代码 EnableCorsAttribute cors = new Enabl ...
- 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 Web API 跨域访问(CORS)
一.客户端用JSONP请求数据 如果你想用JSONP来获得跨域的数据,WebAPI本身是不支持javascript的callback的,它返回的JSON是这样的: {"YourSignatu ...
- Cors 跨域Access-Control-Allow-Origin
1.Access-Control-Allow-Origin 指定格式 The Origin header field has the following syntax: origin = " ...
随机推荐
- c++程序猿经典面试题
1.请问i的值会输出什么? #include"iostream.h" int i=1; void main() { int i=i; cout<<i<<en ...
- 使用SVN clang: error: linker command failed with exit code 1 (use -v to see invocation)
然后上传到该项目SVN仓库上,例如,下面的错误再次发生再拉到本地编译 ld: library not found for -lxxxxxxxxxxxx clang: error: linker com ...
- android 项目中使用对话框统一封装
近期在做拼车项目中使用到了一些对话框,而且在非常多地方都使用到了,既然非常多地方使用到,那么肯定要封装一下,
- 三点半们耐热i哦好家哦i囧囧【
http://pan.baidu.com/share/link?shareid=3011665141&uk=338692646&third=15 http ...
- 《Android内核剖析》读书笔记 第13章 View工作原理【View重绘过程】
计算视图大小的过程(Measure) 视图大小,准确的来说应该是指视图的布局大小:我们在layout.xml中为每个UI控件设置的layout_width/layout_height两个属性被用来设置 ...
- java日历程序版本
//MainFrame.java package com.huowolf.myCalender; import java.awt.BorderLayout; import java.awt.Color ...
- 设计模式初探3——装饰者模式(Decorator Pattern)
装饰者模式:动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. 适用范围: 1. 须要扩展一个类的功能.或给一个类加入附加职责. 2. 须要动态的给一个对象加入功能,这些功 ...
- mysql经常使用的命令
如何登陆数据库 飞机着陆 mysql -u <username> -p 访问本机数据库 mysql -u <username> -D <d ...
- POJ 2533-Longest Ordered Subsequence(DP)
Longest Ordered Subsequence Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 34454 Acc ...
- iOS_8_键盘操作简单
最后效果图: BeyondViewController.h // // BeyondViewController.h // 9_键盘的简单处理 // // Created by beyond on 1 ...