WepApi确实方便好用,没有配置文件,一个apicontroller直接可以干活了。但今天用$.ajax跨域请求的时候总是获取不到数据,用fiddler一看确实抓到了数据,但回到$.ajax函数中,直接触发了error,没有触发success,即使状态码是200。用apiclient或者浏览器直接访问都是ok的。搜罗一番。最终在这篇文章上面找到答案 。http://code.msdn.microsoft.com/windowsdesktop/Implementing-CORS-support-a677ab5d

原因

在默认情况下,为防止CSRF跨站伪造攻击,一个网页从另外一个域的网页获取数据的时候就会受到限制。有一些方法可以突破这个限制,JSONP就是其一。它使用<script> 标签加一个回调函数。但JSONP 只支持Get方法。而CORS(Cross-Origin Resource Sharing) 跨域资源共享,是一种新的header规范,可以让服务器端放松跨域的限制,可以根据header来切换限制或不限制跨域请求。它支持所有的Http请求方式。跨域的资源请求带有一个Http header:Origin,如果服务器支持CORS,响应就会带有一个header:Access-Control-Allow-Origin ,也有一些特殊的请求。采用 HTTP “OPTIONS” 的方式,hearder中带有Access-Control-Request-Method或Access-Control-Request-Headers,服务器响应的hearder中需要带有Access-Control-Allow-Methods,Access-Control-Allow-Headers才行。

实现

那怎么实现CORS呢,这用到了Message Handler。它可以在管道中拦截并修改Request,代码如下:

 public class CorsHandler : DelegatingHandler
{
const string Origin = "Origin";
const string AccessControlRequestMethod = "Access-Control-Request-Method";
const string AccessControlRequestHeaders = "Access-Control-Request-Headers";
const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
const string AccessControlAllowHeaders = "Access-Control-Allow-Headers"; protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
bool isCorsRequest = request.Headers.Contains(Origin);
bool isPreflightRequest = request.Method == HttpMethod.Options;
if (isCorsRequest)
{
if (isPreflightRequest)
{
return Task.Factory.StartNew<HttpResponseMessage>(() =>
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First()); string accessControlRequestMethod = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault();
if (accessControlRequestMethod != null)
{
response.Headers.Add(AccessControlAllowMethods, accessControlRequestMethod);
} string requestedHeaders = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders));
if (!string.IsNullOrEmpty(requestedHeaders))
{
response.Headers.Add(AccessControlAllowHeaders, requestedHeaders);
} return response;
}, cancellationToken);
}
else
{
return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>(t =>
{
HttpResponseMessage resp = t.Result;
resp.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
return resp;
});
}
}
else
{
return base.SendAsync(request, cancellationToken);
}
}
}

然后在Global中加入:

 protected void Application_Start(object sender, EventArgs e)
{
GlobalConfiguration.Configuration.MessageHandlers.Add(new CorsHandler());
WebApiConfig.Register(GlobalConfiguration.Configuration);
}

脚本:

  $.ajax({
// url: "http://localhost:11576/api/Values",
url: "http://localhost:39959/api/user/login?name=niqiu&pwd=123456",
type: "GET",
//contentType: "application/json;",
success: function(result) {
alert(result.status);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("出错!XMLHttpRequest:" + XMLHttpRequest.status);
}
});

这样访问就ok了。

随机推荐

  1. Linux_arm驱动之按键模拟脉冲实现定时器的精确计时

    /***************************************************************** 内核驱动部分button_ker.c ************** ...

  2. BingMap

    Application name Key details BngMapTest Key:25nTPiuDe0kxITMR1ymE~j5IlskEImiwGsGmAnsCftQ~Ap0HigfJujLq ...

  3. spring 事务:注解方式

    (1) .<context:component-scan base-package="*.*" /> 该配置隐式注册了多个对注解进行解析的处理器,如: Autowire ...

  4. 其他浏览器(firefox,chrome)可以上网 ie(Internet Explorer)无法上网 解决方法

    http://blog.csdn.net/andywangcn/article/details/8945366

  5. shell学习--grep2

    grep相关的练习,解释下面grep表达式的含义: grep '\<Tom\>' file 打印file中包含单词 Tom的行 grep 'Tome Savage' file 打印file ...

  6. 《UML大战需求分析》阅读笔记4

    流程分析利器之二,状态机图. 状态机图也可以叫状态图,也是用来分析流程的,之前的活动图的主体是事件的行为,而状态机图主要描述的是事件的状态. 开始:实心圆点: 结束:点加环:(与活动图一样) 状态:圆 ...

  7. hdu 1181(DFS)变 形 课

    变形课 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submis ...

  8. java基本数据类型取值范围

    在JAVA中一共有八种基本数据类型,他们分别是 byte.short.int.long.float.double.char.boolean 整型 其中byte.short.int.long都是表示整数 ...

  9. mysql删除开放用户权限

    来访用户ODBC 1,在本地的cmd中用root用户进入mysql2,创建一个ODBC的用户create user 'ODBC'@'localhost';查看用户是否创建成功select user,h ...

  10. 【计算几何】bzoj1043 [HAOI2008]下落的圆盘

    n^2枚举圆盘,用两圆圆心的向量的极角+余弦定理求某个圆覆盖了该圆的哪一段区间(用弧度表示),最后求个区间并. 注意--精度--最好再累计区间的时候,把每个区间的长度减去EPS,防止最后覆盖的总区间超 ...