WebAPI CORS 支持跨域POST
2015-12-03 11:04
232 查看
网上一般能找到的都是通过Microsoft.AspNet.WebApi.Cors来实现CORS,这是通过dll的方式,然后还有一种是通过config的方式
1、dll方式实现CORS
这种方式的好处就是控制精细,可以对同一个站点下的action分别赋予不同的CORS设置,具体怎么实现这里就不多说了,不了解的可以看/article/1308124.html
然后这里记录下实际可能会出现的问题
a) System.Web.Http未能加载
这个可以直接下载dll,然后添加到项目引用中
b) 尝试访问安全关键类型
这是因为System.Web.Http版本不一致,本人做测试时Microsoft.AspNet.WebApi.Cors版本为5.2.3,而默认添加的System.Web.Http为4.0版本,通过Nuget重新下载个匹配版本,然后将引用调整为5.2.3版本的引用即可修复问题
[html] view
plaincopy
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net45" />
c) 默认appsetting配置导致的错误
http://diaosbook.com/Post/2013/12/27/tips-for-aspnet-webapi-cors(备注,个人测试时用的Vs2013未遇到此种问题)
2、config方式实现CORS
在Web.config的system.webServer配置节下增加配置,这种方式的好处是简单,只要在这里加了这个配置,那么所有的api都可以按同一种规则支持跨域请求
[html] view
plaincopy
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE" />
</customHeaders>
</httpProtocol>
如果是HTTP Basic Access authentication,似乎还需要个<add name="Access-Control-Allow-Credentials" value="true" />,此处还未验证
最后补充个Cors相关说明:/article/1308127.html
以及官方链接:http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
===========================================================================================================
Edi Wang
2013-12-27 Friday 16:51
前几天我在帮队友撸一个WebAPI的跨域访问问题,被爆出了翔,今天正好有时间总结一下经验。
首先一个最坑之坑,也是ASP.NET官网上都没有提到的坑,是Web.config里的配置。大家看这个建立WebAPI项目之后,默认的Web.config:
它居然把OPTIONS类型的请求给撸掉了!然而,在jQuery等框架里发起CORS请求的时候,虽然你写的可能是“GET”,但是现在的浏览器是会自动把这个GET先撸成OPTIONS去访问服务的,这也叫“preflight”请求。如果你的服务拒绝OPTIONS这个verb,你会得到一个405的结果(用fiddler就可以看到)。
所以,要让WebAPI支持CORS,第一步就是在web.config里把“<remove name="OPTIONSVerbHandler" />”删掉。
接下来,要实现CORS,有两种办法。一是在客户端完成(要求对WebAPI做少量拓展),二是在服务端(WebAPI)本身做支持。
一、客户端用JSONP请求数据
如果你想用JSONP来获得跨域的数据,WebAPI本身是不支持javascript的callback的,它返回的JSON是这样的:
然而,JSONP请求期望得到这样的JSON:
所以我们需要对WebAPI做拓展,让它支持这样的callback。我找到了两种办法。
1. 我个人比较喜欢的是来自stackoverflow的方案:
http://stackoverflow.com/questions/9421312/jsonp-with-asp-net-web-api/18206518#18206518
自己写个Attribute,来给返回的JSON包上callback
然后在要被调用的方法前加上这个Attribute:
非常简洁明了,但是这种方法有个缺点,就是被加了[JsonCallback]的方法,只能适用于JSONP的请求。如果你希望API能被各种场合的客户端调用,还是在服务端提供支持吧。
2. 通过自定义JsonMediaTypeFormatter实现
参见 Artech大神的文章:/article/1308126.html
二、服务端实现
支持CORS最地道的方法当然是在服务端提供支持,按官网的办法,100%成功。http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
主要步骤是:
1. 到nuget上装一个包:http://www.nuget.org/packages/Microsoft.AspNet.WebApi.Cors/
2. 在WebApiConfig.Register方法中加入代码:
3. 在Controller上加上Attribute:
这个域名是可以配置的,具体还请参考上面给出的官网教程。
最后,还要告诉大家一个坑,在服务端完提供支持以后,不要高兴的太早,如果你用jQuery.ajax()的方式去请求,还是会爆的:
经过无数次爆破,终于发现,只要把dataType和contentType两个参数去掉,就肯定不会爆了!!!虽然不知道为什么,但代码能用了,码农就能按时回家了:)
1、dll方式实现CORS
这种方式的好处就是控制精细,可以对同一个站点下的action分别赋予不同的CORS设置,具体怎么实现这里就不多说了,不了解的可以看/article/1308124.html
然后这里记录下实际可能会出现的问题
a) System.Web.Http未能加载
这个可以直接下载dll,然后添加到项目引用中
b) 尝试访问安全关键类型
这是因为System.Web.Http版本不一致,本人做测试时Microsoft.AspNet.WebApi.Cors版本为5.2.3,而默认添加的System.Web.Http为4.0版本,通过Nuget重新下载个匹配版本,然后将引用调整为5.2.3版本的引用即可修复问题
[html] view
plaincopy
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net45" />
c) 默认appsetting配置导致的错误
http://diaosbook.com/Post/2013/12/27/tips-for-aspnet-webapi-cors(备注,个人测试时用的Vs2013未遇到此种问题)
2、config方式实现CORS
在Web.config的system.webServer配置节下增加配置,这种方式的好处是简单,只要在这里加了这个配置,那么所有的api都可以按同一种规则支持跨域请求
[html] view
plaincopy
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE" />
</customHeaders>
</httpProtocol>
如果是HTTP Basic Access authentication,似乎还需要个<add name="Access-Control-Allow-Credentials" value="true" />,此处还未验证
最后补充个Cors相关说明:/article/1308127.html
以及官方链接:http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
===========================================================================================================
ASP.NET Web API 跨域访问(CORS)要注意的地方
Edi Wang2013-12-27 Friday 16:51
6504
Reads 1
Comments
前几天我在帮队友撸一个WebAPI的跨域访问问题,被爆出了翔,今天正好有时间总结一下经验。首先一个最坑之坑,也是ASP.NET官网上都没有提到的坑,是Web.config里的配置。大家看这个建立WebAPI项目之后,默认的Web.config:
它居然把OPTIONS类型的请求给撸掉了!然而,在jQuery等框架里发起CORS请求的时候,虽然你写的可能是“GET”,但是现在的浏览器是会自动把这个GET先撸成OPTIONS去访问服务的,这也叫“preflight”请求。如果你的服务拒绝OPTIONS这个verb,你会得到一个405的结果(用fiddler就可以看到)。
所以,要让WebAPI支持CORS,第一步就是在web.config里把“<remove name="OPTIONSVerbHandler" />”删掉。
接下来,要实现CORS,有两种办法。一是在客户端完成(要求对WebAPI做少量拓展),二是在服务端(WebAPI)本身做支持。
一、客户端用JSONP请求数据
如果你想用JSONP来获得跨域的数据,WebAPI本身是不支持javascript的callback的,它返回的JSON是这样的:
{"YourSignature": "嫁人要嫁程序员,钱多话少死得早"}
然而,JSONP请求期望得到这样的JSON:
jQuery123456([{"YourSignature": "嫁人要嫁程序员,钱多话少死得早"}])
所以我们需要对WebAPI做拓展,让它支持这样的callback。我找到了两种办法。
1. 我个人比较喜欢的是来自stackoverflow的方案:
http://stackoverflow.com/questions/9421312/jsonp-with-asp-net-web-api/18206518#18206518
自己写个Attribute,来给返回的JSON包上callback
public class JsonCallbackAttribute : ActionFilterAttribute { private const string CallbackQueryParameter = "callback"; public override void OnActionExecuted(HttpActionExecutedContext context) { var callback = string.Empty; if (IsJsonp(out callback)) { var jsonBuilder = new StringBuilder(callback); jsonBuilder.AppendFormat("({0})", context.Response.Content.ReadAsStringAsync().Result); context.Response.Content = new StringContent(jsonBuilder.ToString()); } base.OnActionExecuted(context); } private bool IsJsonp(out string callback) { callback = HttpContext.Current.Request.QueryString[CallbackQueryParameter]; return !string.IsNullOrEmpty(callback); } }
然后在要被调用的方法前加上这个Attribute:
[JsonCallback] public IEnumerable<User> User() { return _user; }
非常简洁明了,但是这种方法有个缺点,就是被加了[JsonCallback]的方法,只能适用于JSONP的请求。如果你希望API能被各种场合的客户端调用,还是在服务端提供支持吧。
2. 通过自定义JsonMediaTypeFormatter实现
参见 Artech大神的文章:/article/1308126.html
二、服务端实现
支持CORS最地道的方法当然是在服务端提供支持,按官网的办法,100%成功。http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
主要步骤是:
1. 到nuget上装一个包:http://www.nuget.org/packages/Microsoft.AspNet.WebApi.Cors/
2. 在WebApiConfig.Register方法中加入代码:
config.EnableCors();
3. 在Controller上加上Attribute:
[EnableCors(origins: "http://myclient.azurewebsites.net", headers: "*", methods: "*")]
这个域名是可以配置的,具体还请参考上面给出的官网教程。
最后,还要告诉大家一个坑,在服务端完提供支持以后,不要高兴的太早,如果你用jQuery.ajax()的方式去请求,还是会爆的:
$.ajax({ url: 'yourCORSurl', data: '', dataType: 'json', type: 'GET', contentType: 'application/json; charset=utf-8', ... })
经过无数次爆破,终于发现,只要把dataType和contentType两个参数去掉,就肯定不会爆了!!!虽然不知道为什么,但代码能用了,码农就能按时回家了:)
相关文章推荐
- 用 LeakCanary 检测内存泄漏
- 单源点最短路径
- PHP字符串处理函数库
- iOS Developer Program
- java学习笔记-设计模式9(代理模式)
- Centos 7 yum 安装Apache
- HDOJ 5427 A problem of sorting
- Android应用启动优化:一种DelayLoad的实现和原理
- 【Problems】 当eclipse出现乱码
- 仿射变换OpenCV实现的最小二乘优化
- GLIDE 的 一些用法
- 转载:《TypeScript 中文入门教程》 3、接口
- Jmeter测试工具的下载使用
- KMP算法--c语言实现
- android源码下载地址
- 第一个web自动化
- Git教程
- iOS 开发笔记和技巧总结 (四)
- ReactiveCocoa 监听Enabled和添加Command出错的处理方法
- java中方法为什么需要返回值?