概述
跨域访问问题指的是在Web开发中,当一个网页的JavaScript代码尝试向不同域名(或端口、协议)的服务器发起HTTP请求时所遇到的限制。这种限制是由浏览器的同源策略(Same-Origin Policy)引起的,目的是为了保护用户隐私和安全,防止恶意网站窃取数据。
跨域访问问题指的是在 Web 开发中,由于安全策略限制,浏览器阻止页面通过 XMLHttpRequest 或 Fetch API 等方式向不同源(域名、协议或端口)的服务器发起 HTTP 请求。这种限制是为了防止恶意网站利用用户的浏览器向其他站点发送恶意请求,从而进行 CSRF(跨站请求伪造)等攻击。
a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。注意:跨域限制访问,其实是浏览器的限制。理解这一点很重要!!!
同源策略规定,网页中的脚本只能从同一个源加载,这个源由协议(如 HTTP 或 HTTPS)、主机名和端口组成。
跨域访问问题情况
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
当前页面url 被请求页面url 是否跨域 原因
当前页面 | 被请求页面url | 是否跨域 | 原因 |
---|---|---|---|
http://www.test.com/ | http://www.test.com/index.html | 否 | 同源(协议、域名、端口号相同) |
http://www.test.com/ | https://www.test.com/index.html | 跨域 | 协议不同(http/https) |
http://www.test.com/ | http://www.baidu.com/ | 跨域 | 主域名不同(test/baidu) |
http://www.test.com/ | http://blog.test.com/ | 跨域 | 子域名不同(www/blog) |
http://www.test.com:8080/ | http://www.test.com:7001/ | 跨域 | 端口号不同(8080/7001) |
跨域访问问题通常出现的情况
- AJAX请求:当使用XMLHttpRequest或Fetch API等技术在前端代码中发起AJAX请求时,如果请求的目标URL与当前页面的域名、端口或协议不一致,就会触发跨域访问限制。
- 跨域资源引用:当在HTML页面中通过
解决跨域访问的方法
- 跨域资源共享(CORS):CORS是一种机制,允许服务器声明哪些源(域、协议、端口)可以访问资源。通过在服务器端设置相应的响应头信息,如Access-Control-Allow-Origin,Access-Control-Allow-Methods等,来实现跨域资源共享。
- JSONP:JSONP是一种利用
CORS跨域
背景
在出现CORS标准之前, 我们还只能通过jsonp(jsonp跨域请求详解)的形式去向“跨源”服务器去发送 XMLHttpRequest 请求,这种方式吃力不讨好,在请求方与接收方都需要做处理,而且请求的方式仅仅局限于GET。所以 ,CORS标准必然是大势所趋,并且市场上绝大多数浏览器都已经支持CORS。(IE10以上)
CORS跨域
CORS通俗地译为跨域资源共享,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制。
跨域访问是指请求一个与自身资源不同源(不同的域名、协议或端口)的资源。不同源可以是不同的域名、协议或端口。
浏览器出于安全考虑设置了同源策略,限制了从脚本内发起跨域请求。但在实际应用中,经常会发生跨域访问。为此,W3C 提供了一个标准的跨域解决方案:跨域资源共享(Cross-Origin Resource Sharing,CORS),支持安全的跨域请求和数据传输。
浏览器将 CORS 请求分为以下两类:
● 简单请求
● 预检请求:防止资源被本来没有权限的请求修改的保护机制。浏览器会在发送实际请求之前使用 OPTIONS 方法发送一个预检请求,从而获知服务端是否允许该跨域请求。服务端确认允许后,才会发起实际的 HTTP 请求。
简单请求
请求满足如下所有条件,为简单请求:
● 请求方法是如下之一:
○ HEAD
○ GET
○ POST
● HTTP 头信息不超过以下几种字段:
○ Cache-Control
○ Content-Language
○ Content-Type
○ Expires
○ Last-Modified
○ Pragma
○ DPR
○ Downlink
○ Save-Data
○ Viewport-Width
○ Width
● Content-Type 的值仅限下列几种:
○ text/plain
○ multipart/form-data
○ application/x-www-form-urlencoded
预检请求
不符合简单请求条件的请求,会在正式通信之前触发一个 OPTIONS 请求进行预检。这类请求为预检请求。
预检请求会在请求头中附带一些正式请求的信息给服务端,主要有:
● Origin:请求源信息。
● Access-Control-Request-Method:接下来的请求类型,如 POST、GET 等。
● Access-Control-Request-Headers:接下来的请求中包含的用户显式设置的 Header 列表。
服务端收到预检请求后,会根据上述附带的信息判断是否允许跨域,通过响应头返回对应的信息:
● Access-Control-Allow-Origin:允许跨域的 Origin 列表。
● Access-Control-Allow-Methods:允许跨域的方法列表。
● Access-Control-Allow-Headers:允许跨域的 Header 列表。
● Access-Control-Expose-Headers:允许暴露的 Header 列表。
● Access-Control-Max-Age:最大的浏览器缓存时间,单位:秒。
● Access-Control-Allow-Credentials:是否允许发送 Cookie。
浏览器会根据返回的 CORS 信息判断是否继续发送真实的请求。以上行为都是浏览器自动完成的,服务端只需要配置特定的 CORS 规则