zoukankan      html  css  js  c++  java
  • .Net 通过设置Access-Control-Allow-Origin来实现跨域访问

    # 前言

    .Net 通过设置Access-Control-Allow-Origin来实现跨域访问,具体哪里可以设置Access-Control-Allow-Origin呢?

    1. web.config中可以设置;
    2. 在IIS服务器站点的功能视图中设置HTTP响应标头;
    3. 通过nginx代理服务器进行设置;
    4. 在每个api接口上添加响应头;
    5. 写一个拦截器,应用到所有控制器上,在拦截器里控制来访域名,动态设置Access-Control-Allow-Origin的值;

    本文主要详细说下第四种和第五种方式,第五种方式也是对第四种方式的一种封装;

    # 为每个API接口单独添加响应头

    1、针对 ASP.NET MVC 项目的Controllers

    public class Default1Controller : Controller
    {
        public ActionResult Test()
        {
            ControllerContext.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
            /*
                --Your code
            */
            return Json("hello");
        }
    }
    

    2、针对 ASP.NET Web API项目的Controllers

    public class TestController : ApiController
    {
        public HttpResponseMessage Get(int id)
        {
            var response = Request.CreateResponse(HttpStatusCode.OK, new {Name="lily",age=10});
    
            response.Headers.Add("Access-Control-Allow-Origin", "*");
            //response.Headers.Add("X-Pagination", "TestHeader");
            //response.Headers.Add("Access-Control-Expose-Headers", "X-Pagination");
            return response;
        }
    }
    
    

    3、针对ASP.NET Web Forms项目中的处理程序

    public class TestHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            context.Response.AddHeader("Access-Control-Allow-Origin", "http://example.com");
            context.Response.AddHeader("Access-Control-Allow-Headers", "*");
            context.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
            context.Response.AddHeader("Access-Control-Allow-Credentials", "true");
            
            //context.Response.AddHeader("TestHeaderToExpose", "test");
            //context.Response.AddHeader("Access-Control-Expose-Headers", "TestHeaderToExpose");
    
            context.Response.ContentType = "text/plain";
            context.Response.Write("Hello World");
        }
    
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
    
    

    # 封装一个拦截器,便于应用到控制器及接口上

    1、针对 ASP.NET MVC 项目的Controllers

    创建一个attribute:

    using System.Web.Mvc;
    
    namespace AllowCross.App_Code
    {
        public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
        {
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
    
                //actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
                //actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Headers", "*");
                //actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
                //context.Response.AddHeader("TestHeader", "test");
                //actionExecutedContext.Response.Headers.Add("Access-Control-Expose-Headers", "TestHeader");
                base.OnActionExecuting(filterContext);
            }
        }
    }
    

    将该attribute添加到action上:

    using AllowCross.App_Code;
    
    namespace AllowCross.Controllers
    {
        public class Default1Controller : Controller
        {
            [AllowCrossSiteJson]
            public ActionResult Test()
            {
                return Json("hello");
            }
        }
    }
    

    2、针对 ASP.NET Web API项目

    创建一个attribute:

    using System.Web.Http.Filters;
    
    namespace WepApiTest.App_Code
    {
        public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
        {
            public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
            {
                if (actionExecutedContext.Response != null)
                {
                    actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
                	//actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
                	//actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Headers", "*");
                	//actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
                	//context.Response.AddHeader("TestHeader", "test");
                	//actionExecutedContext.Response.Headers.Add("Access-Control-Expose-Headers", "TestHeader");
                }
    
                base.OnActionExecuted(actionExecutedContext);
            }
        }
    }
    

    将该attribute添加到acion上:

    using WepApiTest.App_Code;
    
    namespace WepApiTest.Controllers
    {
        public class DefaultController : ApiController
        {
            [AllowCrossSiteJson]
            public IEnumerable<string> Get()
            {
                return new string[] { "value1", "value2" };
            }
        }
    }
    

    也可以将该attribute添加到整个controller上:

    using WepApiTest.App_Code;
    
    namespace WepApiTest.Controllers
    {
        [AllowCrossSiteJson]
        public class DefaultController : ApiController
        {
            public IEnumerable<string> Get()
            {
                return new string[] { "value1", "value2" };
            }
        }
    }
    

    3、针对 ASP.NET Web API 2 还可以使用库:Microsoft.AspNet.WebApi.Cors

    3.1 使用nuget安装Microsoft.AspNet.WebApi.Cors

    使用命令:

    Install-Package Microsoft.AspNet.WebApi.Cors
    

    使用管理器:
    使用nuget安装Microsoft.AspNet.WebApi.Cors

    3.2 打开App_Start/WebApiConfig.cs文件,在WebApiConfig.Register方法中配置WebApi.Cors

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            //配置WebApi.Cors
            config.EnableCors();
    
            config.MapHttpAttributeRoutes();
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
    
    

    3.3 在Controller上添加[EnableCors]属性

    using System.Web.Http;
    using System.Web.Http.Cors;
    
    namespace WepApiTest.Controllers
    {
        [EnableCors(origins: "http://WepApiTest.com", headers: "*", methods: "*")]
        public class TestController : ApiController
        {
            // GET: api/Test
            public IEnumerable<string> Get()
            {
                return new string[] { "value1", "value2" };
            }
        }
    }
    

    3.3 在Controller中的action上添加[EnableCors]属性

    using System.Web.Http;
    using System.Web.Http.Cors;
    
    namespace WepApiTest.Controllers
    {
        public class TestController : ApiController
        {
            // GET: api/Test
            [EnableCors(origins: "http://WepApiTest.com", headers: "*", methods: "*")]
            public IEnumerable<string> Get()
            {
                return new string[] { "value1", "value2" };
            }
        }
    }
    

    3.4 如果想应用到所有的api controller上,在WebApiConfig.Register方法中进行如下配置

    using System.Web.Http;
    using System.Web.Http.Cors;
    
    namespace WebApplication2
    {
        public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                //配置WebApi.Cors
                var cors = new EnableCorsAttribute("www.example.com", "*", "*");
                config.EnableCors(cors);
    
                config.MapHttpAttributeRoutes();
    
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
            }
        }
    }
    

    3.5 设置origins、HTTP methods、request headers示例

    // Allow CORS for all origins. (Caution!)
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    
    [EnableCors(origins: "http://www.justsoso.com,http://www.example.com", 
        headers: "*", methods: "*")]
    
    [EnableCors(origins: "http://www.example.com", headers: "*", methods: "get,post")]
    
    [EnableCors(origins: "http://example.com", 
        headers: "accept,content-type,origin,x-my-header", methods: "*")]
    

    3.6 Pass credentials in cross-origin requests

    Credentials require special handling in a CORS request. By default, the browser does not send any credentials with a cross-origin request. Credentials include cookies as well as HTTP authentication schemes. To send credentials with a cross-origin request, the client must set XMLHttpRequest.withCredentials to true.

    Using XMLHttpRequest directly:

    var xhr = new XMLHttpRequest();
    xhr.open('get', 'http://www.example.com/api/test');
    xhr.withCredentials = true;
    

    In jQuery:

    $.ajax({
        type: 'get',
        url: 'http://www.example.com/api/test',
        xhrFields: {
            withCredentials: true
        }
    

    In addition, the server must allow the credentials. To allow cross-origin credentials in Web API, set the SupportsCredentials property to true on the [EnableCors] attribute:

    [EnableCors(origins: "http://myclient.azurewebsites.net", headers: "*", 
        methods: "*", SupportsCredentials = true)]
    

    If this property is true, the HTTP response will include an Access-Control-Allow-Credentials header. This header tells the browser that the server allows credentials for a cross-origin request.

    If the browser sends credentials, but the response does not include a valid Access-Control-Allow-Credentials header, the browser will not expose the response to the application, and the AJAX request fails.

    Be careful about setting SupportsCredentials to true, because it means a website at another domain can send a logged-in user's credentials to your Web API on the user's behalf, without the user being aware. The CORS spec also states that setting origins to "*" is invalid if SupportsCredentials is true.

    3.7 浏览器支持情况

    库Web API CORS是服务端的处理方法,还必须要求客户端支持CORS,支持情况请查看该地址:
    https://caniuse.com/#feat=cors

    # 低版本IE实现跨域

    参考:Cross-Domain AJAX for IE8 and IE9

    # 参考

    Setting Access-Control-Allow-Origin in ASP.Net MVC - simplest possible method
    Microsoft.AspNet.WebApi.Cors
    跨域资源共享 CORS 详解

    ——————————————————————————————————————————————

  • 相关阅读:
    Pandas也能轻松绘图,简单而又漂亮
    笔试题: 二叉排序数左移k个
    补题next_permutation
    从HTTP到HTTPS
    HTTP首部字段详解
    HTTP请求方法及响应状态码详解
    HTTP报文格式详解
    TCP/IP网络基础
    Netty学习笔记
    ZooKeeper学习笔记
  • 原文地址:https://www.cnblogs.com/willingtolove/p/11175599.html
Copyright © 2011-2022 走看看