目录

# 前言

.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

使用管理器:

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

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

.Net 通过设置Access-Control-Allow-Origin来实现跨域访问的更多相关文章

  1. 【转载】ASP.NET MVC设置允许跨域访问

    默认情况下,浏览器端发送Ajax请求一般被禁止跨域访问,如A域名网站访问B域名网站的请求会被终止,在ASP.NET MVC项目中,我们可以配置相应的设置项,允许网站的接口跨域访问,主要需要设置Acce ...

  2. Access control allow origin 简单请求和复杂请求

    原文地址:http://blog.csdn.net/wangjun5159/article/details/49096445 错误信息: XMLHttpRequest cannot load http ...

  3. [转] Chrome - 浏览器跨域访问设置(附:新老版本两种设置方法)

    [From] http://www.hangge.com/blog/cache/detail_1703.html 在进行前后分离的 webapp 开发,或者 H5 移动 App 开发时,我们会使用 P ...

  4. ajax 设置Access-Control-Allow-Origin实现跨域访问

    ajax跨域访问是一个老问题了,解决方法很多,比较常用的是JSONP方法,JSONP方法是一种非官方方法,而且这种方法只支持GET方式,不如POST方式安全. 即使使用jquery的jsonp方法,t ...

  5. ajax设置Access-Control-Allow-Origin实现跨域访问

    ajax跨域访问 1.jsonp方法,jsonp方法是一种非官方方法,这种方法只支持GET方式, 不如POST方式安全.(即使使用jquery的jsonp方法,type设为POST, 也会自动变为GE ...

  6. PHP 通过设置P3P头来实现跨域访问COOKIE

    CentOS的系统(Linux 内核) 编辑HOST vi /etc/hosts 加入127.0.0.1 www.a.com127.0.0.1 www.b.com 首先:创建 a_setcookie. ...

  7. 通过设置P3P头来实现跨域访问COOKIE

    通过设置P3P头来实现跨域访问COOKIE 实际工作中,类似这样的要求很多,比如说,我们有两个域名,我们想实现在一个域名登录后,能自动完成另一个域名的登录,也就是PASSPORT的功能. 我只写一个大 ...

  8. java后台设计简单的json数据接口,设置可跨域访问,前端ajax获取json数据

    在开发的过程中,有时候我们需要设计一个数据接口.有时候呢,数据接口和Web服务器又不在一起,所以就有跨域访问的问题. 第一步:简单的设计一个数据接口. 数据接口,听起来高大上,其实呢就是一个简单的Se ...

  9. Java Web中实现设置多个域名跨域访问

    添加以下设置可允许所有域名跨域访问: response.setHeader("Access-Control-Allow-Origin","*"); 但在实际应用 ...

随机推荐

  1. Xamarin简介

    简介 简单来说,Xamarin提供了使用C#完成iOS,Android和Windows Phone三个移动平台开发的可能性Xamarin包括Xamarin.Andriod.Xamarin.IOS.Xa ...

  2. WPF 4 DataGrid 控件(进阶篇二)

    原文:WPF 4 DataGrid 控件(进阶篇二)      上一篇<WPF 4 DataGrid 控件(进阶篇一)>中我们通过DataGridTemplateColumn 类自定义编辑 ...

  3. Redis 一些高级用法

    延迟消息队列 利用 expire keyspace notification Redis 过期时,会向特定的消息队列发送消息,监听该消息队列 在 redis.conf 修改 notify-keyspa ...

  4. C#并口热敏小票打印机打印位图

    原文:C#并口热敏小票打印机打印位图 最近一直在研究并口小票打印机打印图片问题,这也是第一次和硬件打交道,不过还好,最终成功了.   这是DEMO的窗体:   下面是打印所需要调用的代码: class ...

  5. WPF中的PathAnimation(路径动画)

    原文:WPF中的PathAnimation(路径动画) WPF中的PathAnimation(路径动画)                                                 ...

  6. List<T>多字段排序的一个通用类

    本文中的方法旨在解决通用的问题,非常注重效率的地方,还应该针对具体的类去写排序方法. 废话不多说,直接上代码 具体使用场景: 要排序的类 1 public class bb 2 { 3 public ...

  7. virtualbox ubuntu16.04 自动挂载共享文件夹

    为了操作方便,需要ubuntu 在开机运行时自动挂载共享文件夹,ubuntu的版本是16.04,宿主机是win10,步骤如下: 1. 在virtualbox “设备”-“共享文件夹”中设置共享文件夹如 ...

  8. Windows窗体原理及控件WM_DRAWITEM和子类化重绘演示文件

    http://download.csdn.net/detail/wenzhou1219/6783959

  9. 测试 Components 与 Controls 的区别(嵌套在Panel上的Edit,依然是Form1的Component)

    本例效果图: 代码文件: unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, ...

  10. NSmutableArray 的实现原理机制

    古老的C数组: 优点:查询速度很快,直接通过下表找到对应的值 缺点:修改.删除数据很慢,需要移动基于所有的其他的元素   插入和删除一个元素,需要移动后面所有的元素 改进的目标:实现快速增加,删除 N ...