一、客户端用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大神的文章: http://www.cnblogs.com/artech/p/cors-4-asp-net-web-api-03.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两个参数去掉

方法二:配置 web.config

在  <system.webServer> 标签内添加以下代码

<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>

然而这里以为搞掂收工,谁知还有一个大坑

当你发送请求时,它居然把OPTIONS类型的请求给撸掉了!在jQuery等框架里发起CORS请求的时候,虽然你写的可能是“GET”,但是现在的浏览器是会自动把这个GET先撸成OPTIONS去访问服务的,这也叫“preflight”请求。如果你的服务拒绝OPTIONS这个verb,你会得到一个405的结果(用fiddler就可以看到)。

所以,要让WebAPI支持CORS,第一步就是在web.config里把“ <remove name="OPTIONSVerbHandler" /> ”删掉。

现在就可以正常访问了。

注意:

当使用方法一的时候,放在web Api的静态文件资源,比如图片,后台把图片路径传给前台后,前台通过jq想把图片转成base64 就发生跨域问题,

如果需要实现,只能采用第二种方法。

ASP.NET Web API 跨域访问(CORS)的更多相关文章

  1. ASP.NET Web API 跨域访问(CORS)要注意的地方

    一.客户端用JSONP请求数据 如果你想用JSONP来获得跨域的数据,WebAPI本身是不支持javascript的callback的,它返回的JSON是这样的: {"YourSignatu ...

  2. ASP.NET Web API 跨域访问

    自定义特性 要在WebApi中实现JSONP,一种方式是实现自定义特性  http://stackoverflow.com/questions/9421312/jsonp-with-asp-net-w ...

  3. Web Api跨域访问配置及调用示例

    1.Web Api跨域访问配置. 在Web.config中的system.webServer内添加以下代码: <httpProtocol> <customHeaders> &l ...

  4. Web API 跨域访问(CORS)

    1.在web.config里把“    <remove name="OPTIONSVerbHandler" />  ”删掉. 2. 到nuget上装一个包:    ht ...

  5. asp.net web api 跨域问题

    缘起 以前在asp.net mvc时代,很少出现跨域问题 自从使用了asp.net web api + angular (1/2)之后,开始有跨域问题了. 简单普及下跨域: 我的理解是只要是前台页面与 ...

  6. asp.net web api 跨域,带cookie

    官网上有一个介绍 http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api 但是只支 ...

  7. ASP.NET web api 跨域请求

    1.学习文章:AJAX 跨域请求 - JSONP获取JSON数据 1.asp.net代码 参考文章:http://www.sxt.cn/info-2790-u-756.html (1).增加CorsH ...

  8. ASP.Net开发WebAPI跨域访问(CORS)的精简流程

    1: Web.config里有一行: <remove name="OPTIONSVerbHandler" /> 这个要删除. 2: nuget安装Microsoft.A ...

  9. web api 跨域访问

    在工程中 Install-Package Microsoft.AspNet.WebApi.Cors 在 webapiconfig.cs中 config.EnableCors(); 在 控制器中, [E ...

随机推荐

  1. 日期格式代码出现两次的错误 ORA-01810

    错误的原因是使用了两次MM . 一.Oracle中使用to_date()时格式化日期需要注意格式码 如:select to_date('2005-01-01 11:11:21','yyyy-MM-dd ...

  2. 解决 Springboot Unable to build Hibernate SessionFactory @Column命名不起作用

    问题: Springboot启动报错: Caused by: org.springframework.beans.factory.BeanCreationException: Error creati ...

  3. 【原】AFNetworking源码阅读(六)

    [原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...

  4. spring源码分析之context

    重点类: 1.ApplicationContext是核心接口,它为一个应用提供了环境配置.当应用在运行时ApplicationContext是只读的,但你可以在该接口的实现中来支持reload功能. ...

  5. 火星坐标、百度坐标、WGS-84坐标相互转换及墨卡托投影坐标转经纬度JavaScript版

    火星坐标 火星坐标是国家测绘局为了国家安全在原始坐标的基础上进行偏移得到的坐标,基本国内的电子地图.导航设备都是采用的这一坐标系或在这一坐标的基础上进行二次加密得到的.火星坐标的真实名称应该是GCJ- ...

  6. java中易错点(一)

    由于replaceAll方法的第一个参数是一个正则表达式,而"."在正则表达式中表示任何字符,所以会把前面字符串的所有字符都替换成"/".如果想替换的只是&qu ...

  7. 注释生成Api文档

    1.开发背景 最近一直在写dubbo接口,以前总是用word文档写接口描述然后发给别人.现在太多了,而且跟别人对接联调的人家急着用,根本没时间去写word文档.那就想想怎么用doc文档注释自动生成接口 ...

  8. Dynamics CRM 之ADFS 使用 WID 的独立联合服务器

    ADFS 的使用 WID 的独立联合服务器适用于自己的测试环境,常用的就是在虚机中使用. 拓扑图如下: wID:联合身份验证服务配置为使用 Windows 内部数据库

  9. Linux监控工具介绍系列——OSWatcher Black Box

      OSWatcher Balck Box简介 OSWatcher Black Box (oswbb)是Oracle开发.提供的一个小巧,但是实用.强大的系统工具,它可以用来抓取操作系统的性能指标,用 ...

  10. 二叉树的创建和遍历(C版和java版)

    以这颗树为例:#表示空节点前序遍历(根->左->右)为:ABD##E##C#F## 中序遍历(左->根->右)为:#D#B#E#A#C#F# 后序遍历(左->右-> ...