zoukankan      html  css  js  c++  java
  • .net webapi跨域方法整理

    方法一

    在Web.Config里面加上了配置信息:

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

    这样配置之后,我自己做Get测试,用JQ来调用也是ok的,我就以为跨域的设置已经做完了,然而天坑来了,Post操作调用不了,整天返回405错误,我就郁闷了,是怎么回事呢。

    上网查了一下跨域调用的原理,发现在跨域POST之前,是有一次OPTION方法调用,是用来确认是否运行跨域POST的握手确认过程。然后继续往下查,发现通过VS自建WebAPI工程默认有OPTION处理,默认是不允许跨域的。

    所以我就在Web.Config里面把这几个代码注释掉了

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

    最后跨域的POST请求通过了,用JQ和axios测试的。

    方法二

    首先配置Web.config文件

    在配置文件中到system.webServer节点,并 追加 如下节点:

    <httpProtocol>
          <customHeaders>
            <!--响应类型 (值为逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法)-->
            <add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS"/>
            <!--响应头设置(Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain)-->
            <add name="Access-Control-Allow-Headers" value="x-requested-with,content-type"/>
            <!--如果设置 Access-Control-Allow-Origin:*,则允许所有域名的脚本访问该资源-->
            <add name="Access-Control-Allow-Origin" value="*" />
            <!--<add name="Access-Control-Allow-Origin" value="http://domain1.com, http://domain2.com" />  设置允许跨域访问的网址-->
          </customHeaders>
        </httpProtocol>

    然后配置Global.asax文件

    在WebApiApplication : System.Web.HttpApplication
    类中新增如下方法:

    /// <summary>
            /// 跨域设置  
            /// </summary>
            protected void Application_BeginRequest()
            {
                //OPTIONS请求方法的主要作用:
                //1、获取服务器支持的HTTP请求方法;也是黑客经常使用的方法。
                //2、用来检查服务器的性能。如:AJAX进行跨域请求时的预检,需要向另外一个域名的资源发送一个HTTP OPTIONS请求头,用以判断实际发送的请求是否安全。
                if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
                {
                    //表示对输出的内容进行缓冲,执行page.Response.Flush()时,会等所有内容缓冲完毕,将内容发送到客户端。
                    //这样就不会出错,造成页面卡死状态,让用户无限制的等下去
                    Response.Flush();
                }
            }

    到此配置结束。

    方法三

    使用CORS跨域

    首先介绍下CORS如何使用,在WebApiCORS项目上面使用Nuget搜索“microsoft.aspnet.webapi.cors”,安装第一个

    Install-Package Microsoft.AspNet.WebApi.Cors
    

    然后在App_Start文件夹下面的WebApiConfig.cs文件夹配置跨域

    public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                //跨域配置
                config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
    
                // Web API 路由
                config.MapHttpAttributeRoutes();
    
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{action}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
            }
        }

    我们暂定三个“*”号,当然,在项目中使用的时候一般需要指定对哪个域名可以跨域、跨域的操作有哪些等等。这个在下面介绍。

    IE10、IE11

    谷歌浏览器

    IE8、IE9

    这个时候又有新问题了,怎么回事呢?我都已经设置跨域了呀,怎么IE8、9还是不行呢?这个时候就有必要说说CORS的浏览器支持问题了。网上到处都能搜到这张图:

     上图描述了CORS的浏览器支持情况,可以看到IE8、9是部分支持的。网上说的解决方案都是Internet Explorer 8 、9使用 XDomainRequest 对象实现CORS。是不是有这么复杂?于是博主各种百度寻找解决方案。最后发现在调用处指定

    jQuery.support.cors = true;
    

     这一句就能解决IE8、9的问题了。具体是在Index.js里面

    jQuery.support.cors = true;
    var ApiUrl = "http://localhost:27221/";
    $(function () {
        $.ajax({
            type: "get",
            url: ApiUrl + "api/Charging/GetAllChargingData",
            data: {},
            success: function (data, status) {
                if (status == "success") {
                    $("#div_test").html(data);
                }
            },
            error: function (e) {
                $("#div_test").html("Error");
            },
            complete: function () {
    
            }
        });
    });

    这句话的意思就是指定浏览器支持跨域。原来IE9以上版本的浏览器、谷歌、火狐等都默认支持跨域,而IE8、9却默认不支持跨域,需要我们指定一下。你可以在你的浏览器里面打印jQuery.support.cors看看。这样设置之后是否能解决问题呢?我们来看效果:

     问题完美解决。至于网上说的CORS对IE8、9的解决方案XDomainRequest是怎么回事,有待实例验证。

    CORS的具体参数设置。

    上文我们使用

    config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
    

     这一句解决了跨域问题,上面说了,这种*号是不安全的。因为它表示只要别人知道了你的请求url,任何请求都可以访问到你的资源。这是相当危险的。所以需要我们做一些配置,限制访问权限。比如我们比较常见的做法如下:

    配置方法一、在Web.Config里面

    然后在WebApiConfig.cs文件的Register方法里面

    配置方法二、如果你只想对某一些api做跨域,可以直接在API的类上面使用特性标注即可。

    [EnableCors(origins: "http://localhost:8081/", headers: "*", methods: "GET,POST,PUT,DELETE")]
        public class ChargingController : ApiController
        {
            /// <summary>
            /// 得到所有数据
            /// </summary>
            /// <returns>返回数据</returns>
            [HttpGet]
            public string GetAllChargingData()
            {
                return "Success";
            }
        }
  • 相关阅读:
    Android JNI 使用的数据结构JNINativeMethod详解 .
    datatable的部分问题处理(动态定义列头,给某行添加事件,初始显示空数据)
    关于boostrap的modal隐藏问题(前端框架)
    三丰云服务器的基本使用(端口)
    Vue+Element的动态表单,动态表格(后端发送配置,前端动态生成)
    云服务器内,nginx安装部署,Xshell,Xftp安装
    免费云服务器的申请(三丰云)
    vue的组件化运用(数据在两个组件互传,小问题总结)
    vue的表单编辑删除,保存取消功能
    datatable动态列处理,重绘表格(敲黑板,划重点!!!我肝了一天半才彻底弄懂这个东西,TAT)
  • 原文地址:https://www.cnblogs.com/ymh2013/p/9265662.html
Copyright © 2011-2022 走看看