本文深入解析CORS(跨域资源共享)原理,阐述其如何突破浏览器同源策略限制。通过对比JSONP等方案,重点介绍在ASP.NET Web API中启用CORS的配置步骤,包括服务端响应头设置及客户端Origin声明,为现代Web应用提供安全高效的跨域访问方案。
引言
引言
跨域问题是前端开发面试中的高频考点,也是日常开发中不可避免的技术难点。其核心原因在于浏览器的安全机制——同源策略,该策略限制JavaScript或Cookie只能访问与当前页面同域的内容。因此,掌握跨域处理技术已成为前端工程师必备的基础技能。
以往处理跨域时,JSONP是常见选择。然而,当产品需求发生变化,要求支持POST请求且数据量较大时,基于GET的JSONP便无法胜任。为此,我们引入了广受关注的CORS(跨域资源共享,Cross-Origin Resource Sharing)技术。本文记录了在此过程中的探索与总结。
CORS的核心能力
CORS的核心能力在于解决标准AJAX请求中的跨域限制问题。
由于原生AJAX存在跨域限制,开发者曾尝试过JSONP、Flash、iframe以及XHR2等多种解决方案。CORS则是其中一种更为现代和标准的解决思路。
CORS的工作原理
CORS的工作原理基于客户端与服务端的协作。
CORS定义了一种跨域访问机制,允许一个域上的网络应用向另一个域提交跨域AJAX请求。实现这一功能的关键在于服务器端只需在响应中发送特定的标头即可,无需复杂的客户端改造。
接下来详细解析CORS的具体实现细节。
跨站HTTP请求与同源策略
跨站HTTP请求(Cross-site HTTP request)指的是发起请求的资源所在域名与请求指向的资源所在域名不一致的HTTP请求。
例如,在Web网站A(www.a.com)中通过<img>标签引入B站(www.b.com)的图片资源(www.b.com/images/1.jpg),此时A站向B站发起的请求即为跨站请求。
对于图片、CSS文件或JavaScript文件等静态资源的跨站请求,浏览器通常是允许的。
然而,如果在脚本中发起HTTP请求,出于安全考虑,浏览器会施加限制。例如,使用XMLHttpRequest对象发起HTTP请求必须严格遵守同源策略。
所谓“同源策略”,是指Web应用程序只能使用XMLHttpRequest对象向发起源所在的域内发起HTTP请求,即请求源和请求目标必须处于同一个域内。
以http://www.a.com为例,其协议为http,域名为www.a.com,默认端口为80。以下是几种同源情况的对比:
•http://www.a.com/index.html 与源同源
•https://www.a.com/a.html 不同源(协议不同)
•http://service.a.com/testService/test 不同源(域名不同)
•http://www.b.com/index.html 不同源(域名不同)
•http://www.a.com:8080/index.html 不同源(端口不同)
为了开发更强大、丰富的Web应用,跨域请求已成为常态。如何在保障安全的前提下进行跨域请求,是亟待解决的问题。
W3C推荐的跨源资源共享机制
W3C推荐了一种新机制,即跨源资源共享(Cross-Origin Resource Sharing, CORS)。
CORS通过客户端与服务端的协作声明来确保请求安全。服务端在HTTP响应头中增加一系列参数(如Access-Control-Allow-Origin),以限制允许访问的域和请求类型。客户端在发起请求时必须声明自己的源(Origin),否则服务器将不予处理,甚至浏览器会直接拦截请求。服务端收到请求后,会比较域信息,仅处理同域或经授权的跨域请求。
CORS跨域请求示例
以下是一个使用CORS实现跨域请求的示例:
客户端代码实现如下:
function getHello() {
var xhr = new XMLHttpRequest();
xhr.open("post", "http://b.example.com/Test.ashx", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// 声明请求源
xhr.setRequestHeader("Origin", "http://a.example.com");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var responseText = xhr.responseText;
console.info(responseText);
}
}
xhr.send();
}
服务端代码实现如下:
public class Test : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
// 声明接受所有域的请求
context.Response.AddHeader("Access-Control-Allow-Origin", "*");
context.Response.Write("Hello World");
}
public bool IsReusable
{
get
{
return false;
}
}
}
在Web API中启用跨域访问
在Web API中启用跨域访问
CORS依赖于服务端与客户端的协作声明,因此在Web API中启用CORS需要进行相应配置。微软ASP.NET团队提供了官方支持跨域的解决方案,只需通过NuGet添加相关包即可。

随后在App_Start/WebApiConfig.cs中进行如下配置即可实现跨域访问:
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.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// 允许Web API跨域访问
EnableCrossSiteRequests(config);
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
}
private static void EnableCrossSiteRequests(HttpConfiguration config) {
var cors = new EnableCorsAttribute(
origins: "*",
headers: "*",
methods: "*"
);
config.EnableCors(cors);
}
}
需要注意的是,IE10以下浏览器不支持CORS,因此目前在国内CORS并非主流的跨域解决方案。但随着Windows 10的发布及IE浏览器的逐渐衰落,可以预见,在不远的将来CORS将成为跨域的标准解决方案。
以上所述是小编给大家介绍的JS跨域解决方案之使用CORS实现跨域,希望对大家有所帮助!