- # 前言
- # 為每個API接口單獨添加響應頭
- # 封裝一個攔截器,便於應用到控制器及接口上
- 1、針對 ASP.NET MVC 項目的Controllers
- 2、針對 ASP.NET Web API項目
- 3、針對 ASP.NET Web API 2 還可以使用庫:Microsoft.AspNet.WebApi.Cors
- 3.1 使用nuget安裝Microsoft.AspNet.WebApi.Cors
- 3.2 打開App_Start/WebApiConfig.cs文件,在WebApiConfig.Register方法中配置WebApi.Cors
- 3.3 在Controller上添加[EnableCors]屬性
- 3.3 在Controller中的action上添加[EnableCors]屬性
- 3.4 如果想應用到所有的api controller上,在WebApiConfig.Register方法中進行如下配置
- 3.5 設置origins、HTTP methods、request headers示例
- 3.6 Pass credentials in cross-origin requests
- 3.7 瀏覽器支持情況
- # 低版本IE實現跨域
- # 參考
# 前言
.Net 通過設置Access-Control-Allow-Origin來實現跨域訪問,具體哪里可以設置Access-Control-Allow-Origin呢?
- web.config中可以設置;
- 在IIS服務器站點的功能視圖中設置HTTP響應標頭;
- 通過nginx代理服務器進行設置;
- 在每個api接口上添加響應頭;
- 寫一個攔截器,應用到所有控制器上,在攔截器里控制來訪域名,動態設置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 詳解
——————————————————————————————————————————————