• web api 跨域请求,ajax跨域调用webapi


    1、跨域问题仅仅发生在Javascript发起AJAX调用,或者Silverlight发起服务调用时,其根本原因是因为浏览器对于这两种请求,所给予的权限是较低的,通常只允许调用本域中的资源,除非目标服务器明确地告知它允许跨域调用。假设我们页面或者应用已在 http://www.test1.com 上了,而我们打算从 http://www.test2.com 请求提取数据。一般情况下,如果我们直接使用 AJAX 来请求将会失败,浏览器也会返回“源不匹配”的错误,"跨域"也就以此由来。

    2、什么是跨域呢?

    JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。通常来说,跨域分为以下几类:
    在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。
     
    3、当发起AJAX跨域(cross domain)调用ASP.NET MVC或者ASP.NET Web API编写的服务时,会发生无法访问的情况。
    出现如下错误信息
    在这里跟大家解释一下 Access-Control-Allow-Origin是HTML5中定义的一种服务器端返回Response header,用来解决资源(比如字体)的跨域权限问题。
    当Access-Control-Allow-Origin后面跟URL 或 *,如果是 URL 则只会允许来自该 URL 的请求,* 则允许任何域的请求
    例如:header('Access-Control-Allow-Origin:http://A.abc.com')||header('Access-Control-Allow-Origin:*')
    意思是说只有当你请求的资源被允许跨域的时候才可以被访问。
    那么我们该怎么设置Access-Control-Allow-Origin呢?
     
    4、第一种是用JSONP来获得跨域的数据,而WebAPI本身是不支持javascript的callback的
     比较一下json与jsonp格式的区别:
    json格式:
    {
        "message":"获取成功",
        "state":"1",
        "result":{"name":"工作组1","id":1,"description":"11"}
    }
    jsonp格式:
    callback({
        "message":"获取成功",
        "state":"1",
        "result":{"name":"工作组1","id":1,"description":"11"}
    })

    看出来区别了吧,在url中callback传到后台的参数是神马callback就是神马,jsonp比json外面有多了一层,callback()。

    只需要给全局注册一个JsonCallbackAttribute,就可以判断接口的访问是属于跨域,还是非跨域,正常的返回。

    因为我们的接口,可能是用来给 移动端(Android 、IOS)做数据接口,也有可能是给网站用,所以,考虑到可能存在跨域的问题。

       GlobalConfiguration.Configuration.Filters.Add(new JsonCallbackAttribute());
    复制代码
     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());
                    //context.Response.Content = new StringContent("C("a")");
                }
    
                base.OnActionExecuted(context);
            }
    
            private bool IsJsonp(out string callback)
            {
                callback = System.Web.HttpContext.Current.Request.QueryString[CallbackQueryParameter];
    
                return !string.IsNullOrEmpty(callback);
            }
    复制代码

    结合下面图片不难开出,请求的地址带回了,callback的参数标识。

    当然也可以用解决跨域问题的jQuery插件-jquery-jsonp,有第一种方式的基础,使用jsonp插件也就比较简单了,server端代码无需任何改动。

    5、服务端直接修改配置文件,个人认为这种方式好一点,毕竟我们所写的api是对外公开的,安全访问的控制还是要通过其他方法来保证。

    针对ASP.NET MVC,只需要在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>

    <handlers>

    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />

    <remove name="OPTIONSVerbHandler" />

    <remove name="TRACEVerbHandler" />

    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

    </handlers>

    </system.webServer>

      

    针对ASP.NET Web API,除了上面这样的设置,还需要添加一个特殊的设计,就是为每个APIController添加一个OPTIONS的方法,但无需返回任何东西。

    public string Options()

    {

    return null; // HTTP 200 response with empty body

    }

    6、还有用CORS(跨域资源共享,Cross-Origin Resource Sharing)来解决的, CORS定义一种跨域访问的机制,可以让AJAX实现跨域访问。CORS 允许一个域上的网络应用向另一个域提交跨域 AJAX 请求。实现此功能非常简单,只需由服务器发送一个响应标头即可。

    hander() 设置,“*”号表示允许任何域向我们的服务端提交请求
         

      也可以设置指定的域名,如域名 http://www.test2.com ,那么就允许来自这个域名的请求

         
    这种没有仔细研究,其实跟上面的配置文件,差不多,都是去设置响应头。
     
    本文是结合好多其他作者的文章:
    http://www.cnblogs.com/chenxizhang/p/3821703.html
    http://www.cnblogs.com/sunxucool/p/3433992.html
    http://www.cnblogs.com/Darren_code/p/cors.html
  • 相关阅读:
    SHELL变量
    LA 2797
    计算几何-圆 模板 训练指南267
    hdu 2553 八皇后问题 基础
    CodeForces 557C Arthur and Table STL的使用
    LA 3263 好看的一笔画 欧拉几何+计算几何模板
    UVA 11178 Morley's Theorem 计算几何模板
    poj 1113
    poj 2187 Beauty Contest 凸包模板+求最远点对
    hdu 1081 dp问题:最大子矩阵和
  • 原文地址:https://www.cnblogs.com/inconceivable/p/5504732.html
Copyright © 2020-2023  润新知