当前访客身份:游客 [ 登录  | 注册加入尚学堂]
启用新域名sxt.cn
新闻资讯

$.ajax 跨域请求 Web Api

我来了! 发表于 2年前  | 评论(0 )| 阅读次数(7473 )|   0 人收藏此文章,   我要收藏


      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了。

分享到:0
关注微信,跟着我们扩展技术视野。每天推送IT新技术文章,每周聚焦一门新技术。微信二维码如下:
微信公众账号:尚学堂(微信号:bjsxt-java)
声明:博客文章版权属于原创作者,受法律保护。如果侵犯了您的权利,请联系管理员,我们将及时删除!
(邮箱:webmaster#sxt.cn(#换为@))
北京总部地址:北京市海淀区西三旗桥东建材城西路85号神州科技园B座三层尚学堂 咨询电话:400-009-1906 010-56233821
Copyright 2007-2015 北京尚学堂科技有限公司 京ICP备13018289号-1 京公网安备11010802015183