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. intel显卡笔记本恢复屏幕亮度调整功能

    更新Intel显卡驱动后不能修改屏幕亮度,可以在注册表里面搜索featuretestcontrol,将f000修改为ffff,重启后就可以通过Fn+F4/F5调整屏幕亮度了. 注:此方法适用于带有in ...

  2. mvc AddImplicitRequiredAttributeForValueTypes

    1.AddImplicitRequiredAttributeForValueTypes (为值类型添加隐式必填验证),默认值 为true.刚在mvc view(html)中会为model的值类型属性( ...

  3. SUSE查看版本号

    suse:~ # lsb_release -dDescription: SUSE Linux Enterprise Server 10 (x86_64) suse:~ # cat /etc/SuSE- ...

  4. php生成器的使用

    按照php的文档说明 一个生成器函数看起来像一个普通的函数,不同的是普通函数返回一个值,而一个生成器可以yield生成许多它所需要的值. 当一个生成器被调用的时候,它返回一个可以被遍历的对象.当你遍历 ...

  5. Java和Ibatis调用存储过程并取得返回值详解

    Java和Ibatis调用存储过程并取得返回值详解 2011-07-19 17:33 jiandanfeng2 CSDN博客 字号:T | T 本文主要介绍了Java和Ibatis调用存储过程的方法, ...

  6. 今天工作中遇到的问题!echart.js

    echart.js 引用的时候, 配置文件和引用的echart.js  应该放在main.js的后面,带有window.onload的js后面.这样的话,不会阻止echar.js的渲染.

  7. Cracking-- 4.7 在一颗二叉树中找两个节点的第一个共同祖先

    分别记录从 root 到 node1 的path 到 node2的path,再找其中共同的部分 struct Node{ int val; struct Node *left; struct Node ...

  8. 关于git(分布式版本控制系统)的一些操作和命令

    很久没上博客写东西了,今天闲着无聊就不想敲代码,所以看了看有没有一些好玩的东西,这不让我发现了git这个源代码版本控制工具,话不多说,就让我来简单的分享一下它的一些操作和命令以及命令所执行的含义吧! ...

  9. scrapy-1.2.1安装失败之解决方法

    前几天重装了win10 64位系统,安装了python-3.5,但是用pip安装scrapy模块时出现如下错误: 看起来是lxml安装的时候出错了,于是先pip install lxml,出现了和上面 ...

  10. 如何解决WebService参数传递中文乱码问题

    1,问题由来 我的主要工作是负责统一适配平台这块,主要任务是提供给客户统一的调用接口,客户使用这个接口可以通过我们再调不同厂家的接口.主要流程如下: 现在客户那边传来的请求报文里面包含中文,使用web ...