zoukankan      html  css  js  c++  java
  • ASP.NET MVC中设置跨域

    ASP.NET MVC中设置跨域

    1、什么是跨域请求

    js禁止向不是当前域名的网站发起一次ajax请求,即使成功respone了数据,但是你的js仍然会报错。这是JS的同源策略限制,JS控制的并不是我们网站编程出现了问题。客户端(网页)和后台编程都可以有效解决这个问题。客户端可以通过JSONP来完成跨域访问;在ES6中为了解除同源策略问题,想出一个办法:当被请求网站为响应头respone添加了一个名为Access-Control-Allow-Origin的header,设置其值等于发起请求网站的域名地址的话,这次请求被视为允许。其中Access-Control-Allow-Origin的值为*时表示允许所有网站的跨域请求。

    2、程序中添加Header头允许客户端跨域请求

    这里有很多方法可以方法可以在返回数据时添加header头。

    请注意:同名Header可以有多个 ,但是运行时使用的是第一个,addHeader添加时,如果同名header已存在,则追加至原同名header后面(不起作用),setHeader,如果同名header已存在,则覆盖一个同名header。

    在action中添加代码

    HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Origin", "*");

    在webconfig添加应用程序配置:

    <system.webServer>
      <httpProtocol>
        <customHeaders>
          <!-- 先移除后添加,确保起作用 -->
          <remove name="Access-Control-Allow-Origin" />
          <remove name="Access-Control-Allow-Headers" />
          <remove name="Access-Control-Allow-Methods" />
          <add name="Access-Control-Allow-Origin" value="*" />
          <add name="Access-Control-Allow-Headers" value="Content-Type" />
          <add name="Access-Control-Allow-Methods" value="*" />
        </customHeaders>
      </httpProtocol>
    </system.webServer>

    添加action过滤器

    不论webapi还是mvc的action,我们都可以重写ActionFilterAttribute过滤器的OnException方法来在action执行完成之后,为http响应添加header头;OnException方法意为在action执行完成之后进行的操作。这个过滤器可以添加在action或者controller上,但是这样就要为每一个action或者controller打上这个过滤器,这里将我们重写的action过滤器添加在了全局的过滤器中,这样,每一个action在执行完成之后都会触发这个过滤器,这里以webapi为例。新建类:

        /// <summary>
        /// 跨域
        /// </summary>
        public class Cores:ActionFilterAttribute
        {
            public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
            {
                base.OnActionExecuted(actionExecutedContext);
                actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin","*");
            }
        }

    代码中注册过滤器

        public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                // Web API 配置和服务
                // 将 Web API 配置为仅使用不记名令牌身份验证。
                config.SuppressDefaultHostAuthentication();
                config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
    
                // Web API 路由
                config.MapHttpAttributeRoutes();
                config.Filters.Add(new Cores());
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
            }
        }

    在Starpup.cs类中设置header头

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.Owin;
    using Owin;
    using System.Web;
    
    [assembly: OwinStartup(typeof(WebApiTest.Startup))]
    
    namespace WebApiTest
    {
        public partial class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                // 不能使用这种方式添加必须使用app的相应方法或者中间件实现
                // HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
    
                //app.UseWebApi();
                app.Use(async (context,next)=> {
                    context.Response.Headers.Set("Access-Control-Allow-Origin", "*");
                    await next();
                });
            }
        }
    }

    startup.cs类是应用启动类,我本来以为直接在方法中直接把HttpContext.Current.Response.AddHeader添加一个头就行了,但是发现不行,必须通过参数app才能成功设置响应头,后来我才知道,这个startup.cs类远不止看到的那么简单!拿出来可以当作好比一本书的一个章节来讲了!以后再深入了解这个类。

    3、引入Script标签获取数据

    一些JSONP之类的客户端跨域请求就不说了,最近发现了构造Script标签也可以作为获取数据的方法,很开心。

    即使服务端不设置允许跨域的header头,js也可以变通获取数据,不过仍然需要服务端的配合。

    这个原理是;当通过script标签的src地址引入某个资源的JS代码的时候,就相当于src地址的JS代码直接就在本地一样。相应的,其他地址的js变量也会引入当前页面
    比如百度地图的JsAPI
    比如雅虎获取IP地址的接口
    接口:http://pv.sohu.com/cityjson
    返回JS代码:var returnCitySN = {"cip": "115.238.95.194", "cid": "330100", "cname": "浙江省杭州市"};
    页面引入
    <script src="http://pv.sohu.com/cityjson"></script>
    然后console.log(returnCitySN)可以直接使用。
    这就提供了思路,

    var script = document.createElement("script"),
    script.src = "http://pv.sohu.com/cityjson";
    script.onload=()=>{
    console.log(returnCitySN);
    }

    但是缺点是,服务端必须返回的是JS代码。

  • 相关阅读:
    MaxScale智能读写
    flask简单demo
    django简单demo
    git原生私服之git&gitweb
    gerrit 解决中文乱码相关配置(转载)
    gerrit集成gitweb:Error injecting constructor, java.io.IOException: Permission denied
    gerrit: Error in POST /accounts/self/preferences
    redmine 配置邮件发送为async后,不能发送邮件(转载)
    gerrit error: unpack failed: error Permission denied
    centos修改hostname以及时间同步
  • 原文地址:https://www.cnblogs.com/gdpw/p/9236661.html
Copyright © 2011-2022 走看看