2026-03-27 07:03:30
所有人都应该知道的跨域及CORS
跨域问题,是Web开发中经常遇到的一个难题。为了理解跨域及CORS(跨域资源共享),我们需要从同源策略讲起。
一、同源策略与跨域
1995年,Netscape提出了同源策略,这是出于安全性的考虑。浏览器在发送Ajax请求时,只接收同域服务器响应的数据资源。所谓同域,指的是协议、域名、端口全部相同。只要这三个条件中有一个不一致,就构成了跨域。
例如,
二、跨域问题的传统解决方案
在CORS出现之前,开发者们采用了多种方法来解决跨域问题,其中最为典型的是JSONP和同域代理。
JSONP:利用<script>标签的src属性来实现跨域数据交互。因为浏览器在解析HTML时,对具有src属性的标签赋予了HTTP请求的能力,且不受跨域限制。服务器返回一段JS代码的函数调用,将服务器数据放在函数实参中,前端提前写好响应的函数准备回调,接收数据。JSONP是目前应用最为广泛的技术解决方案之一。
同域代理:使用Ajax向同域下的后台发送请求,同时携带真实请求的地址及参数。后台接收请求后直接根据地址及参数转发请求,因为后台可以模拟HTTP客户端发送请求,所以没有跨域问题。后台接收到响应数据后再原样返回给前端浏览器,从而实现跨域数据交互。
然而,这两种方法本质上并没有解决Ajax跨域的问题,只是绕开了这个问题而另辟蹊径实现的跨域数据交互。
三、CORS(跨域资源共享)
CORS是浏览器与服务器跨域通信的安全性通信策略。它得益于HTTP-1.1协议版本的推广使用,由一系列传输的HTTP头组成。这些HTTP头有两个作用:一是用于阻止还是允许浏览器向其他域名发起请求;二是用于接受还是拒绝其他域名返回的响应数据。
CORS的请求与响应头
请求头:
Origin:指示获取资源的请求是从什么域发起的。这是浏览器在发现本次为跨域请求时自动添加的。
Access-Control-Request-Headers:用于发起一个预请求,告知服务器正式请求会使用哪些HTTP头。
Access-Control-Request-Method:用于发起一个预请求,告知服务器正式请求会使用哪一种HTTP请求方法。
响应头:
Access-Control-Allow-Origin:指示请求的资源能共享给哪些域,可以是具体的域名或者*表示所有域。
Access-Control-Allow-Credentials:指示当请求的凭证标记为true时,是否响应该请求。
Access-Control-Allow-Headers:用在对预请求的响应中,指示实际的请求中可以使用哪些HTTP头。
Access-Control-Allow-Methods:指定对预请求的响应中,哪些HTTP方法允许访问请求的资源。
Access-Control-Expose-Headers:指示哪些HTTP头的名称能在响应中列出。
Access-Control-Max-Age:指示预请求的结果能被缓存多久。
简单请求与复杂请求
简单请求:满足以下所有条件的请求被视为简单请求:
请求方法必须是GET、HEAD、POST中的一种。
请求头类型只能是Accept、Accept-Language、Content-Language、Content-Type。
请求头Content-Type如果有,值只能是text/plain、multipart/form-data、application/x-www-form-urlencoded中的一种。
请求中的任意XMLHttpRequestUpload对象均没有注册任何事件监听器。
请求中没有使用ReadableStream对象。
复杂请求(需预检请求):不满足上述简单请求条件的请求被视为复杂请求。复杂请求在正式发送前,会先发送一个OPTIONS方法的请求以得到服务器的同意。如果服务器允许本次请求响应的数据可以共享,那么需要添加相应的CORS响应头。
四、CORS的使用
使用CORS解决跨域问题相对简单,但需要注意区分简单请求和复杂请求。对于简单请求,只需在服务器添加Access-Control-Allow-Origin响应头即可。对于复杂请求,除了Access-Control-Allow-Origin外,还需要添加其他相关的CORS响应头,如Access-Control-Allow-Headers和Access-Control-Allow-Methods等。
五、总结
通过理解CORS的原理和使用方法,我们可以更加安全、高效地解决Web开发中的跨域问题。