同源策略
Web内容的源用于访问它的URL的协议(方案)、主机(域名)、和端口号。只有当协议、主机、域名都匹配时,两个对象才具有相同的起源,即Origin相同。
浏览器的同源策略目的是为了保护用户的信息安全,为了防止恶意网站窃取用户在浏览器上的数据,如果不是同源的站点,将不能进行如下操作 :
- Cookie、LocalStorage 和 IndexDB 无法读写
- DOM 和 Js对象无法获得
- AJAX请求不能发送
跨域并不是请求发不出去,而是请求能发出去且服务端能收到请求并正常返回结果,只是结果被浏览器拦截。
跨域请求方案
CORS
CORS 是一种机制,允许在浏览器中通过特定的 HTTP 头来控制跨域请求。
它基于服务器的信任模型,服务器可以发送额外的响应头来指示浏览器是否允许跨域请求
简单请求需要满足以下两大条件
- 请求方法是以下三种方法之一:HEAD、GET、POST。
- HTTP的头信息不超出以下几种字段:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type只限于三个值 application/x-www-form-urlencoded、multipart/form-data、text/plain
非简单请求
- 请求方法为PUT、DELETE等不是简单请求允许的方法;
- 请求中的Content-Type不是application/x-www-form-urlencoded、multipart/form-data、text/plain;
- 请求中包含自定义的请求头字段(如Authorization);
- 非简单请求会先发起一个预检请求(OPTIONS请求),询问服务端是否允许实际请求;
- 服务端需要先处理预检请求,验证并确认是否允许实际请求;
简单请求不需要发送预检请求,直接进行验证
简单请求
- 当浏览器发现发起的ajax请求是简单请求时,会在请求头中携带一个字段:Origin.
- Origin中会指出当前请求属于哪个域(协议+域名+端口)。服务会根据这个值决定是否允许其跨域。
- 如果服务器允许跨域,需要在返回的响应头中携带下面信息
常见的解决跨域问题的HTTP响应头包括:
- Access-Control-Allow-Origin: 允许跨域请求的来源域名。可以设置为具体的域名,也可以设置为"*"表示允许所有来源。
- Access-Control-Allow-Methods: 允许的请求方法,例如 GET、POST、PUT、DELETE。
- Access-Control-Allow-Headers: 允许的请求头,例如 Content-Type、Authorization 等。
- Access-Control-Max-Age: 预检请求的有效期,单位为秒。可以减少预检请求的发送频率。
- Access-Control-Allow-Credentials: 是否允许发送 Cookie。如果需要发送 Cookie,需要设置为 true。
操作cookie,需要满足3个条件
- 服务的响应头中需要携带Access-Control-Allow-Credentials并且为true。
- 浏览器发起ajax需要指定withCredentials 为true
- 响应头中的Access-Control-Allow-Origin一定不能为*,必须是指定的域名
优点
CORS支持所有类型的HTTP请求,是跨域HTTP请求的根本解决方案
缺点
对浏览器要求较高,低版本浏览器无法兼容
jsonp
在浏览器中, <script> 、<img>、<iframe>、<link>等标签都可以跨域加载,而不受浏览器的同源策略的限制, 这些带src属性的标签每次加载的时候,实际上都是浏览器发起一次GET请求
浏览器传递callback参数到后端,后端返回数据时会将callback参数作为函数名来包裹数据,从而浏览器就可以跨域请求数据并制定函数来自动处理返回数据。
jsonp跨域优点:
jsonp兼容性强,适用于所有浏览器,尤其是IE10以下浏览器
jsonp跨域缺点
- 没有关于调用错误的处理
- 只支持GET请求,不支持POST以及大数据量的请求,也无法拿到相关的返回头,状态码等数据
- callback参数恶意注入,可能会造成xss漏洞
- 无法设置资源访问权限
代理服务器
服务器端代理是一种通过在服务器上转发请求来处理跨域请求的方法。
它涉及设置一个位于客户端和目标服务器之间的代理服务器,客户端将请求发送到代理服务器,代理服务器再将请求转发给目标服务器,并将响应返回给客户端。
反向代理服务器
反向代理是一种代理服务器的布置方式,它将客户端请求转发到内部资源服务器,并将响应返回给客户端。
与正向代理不同,反向代理透明地对外提供服务,客户端无需知道实际提供服务的服务器
反向代理可以使用常见的Web服务器软件(如Nginx、Apache)来配置和搭建
反向代理跨域也是基于CORS
反向代理服务器可以在处理来自客户端的请求时,添加一些HTTP响应头信息,使跨域请求能够被浏览器接受。
反向代理服务器可以充当中间层,对外隐藏真实服务端,同时处理跨域请求,确保数据的安全传输和合法访问。
当相同的父域实现cookie共享
在网站的同一父域下(例如 a.cn.com 和 b.cn.com),设置 Cookie 的 domain 属性为 .cn.com
如果你想在 a.cn.com、b.cn.com 这两个子域名下共享 Cookie,你可以在设置 Cookie 时将 domain 属性设置为 .cn.com,这样这个 Cookie 就可以在所有以 .cn.com 结尾的子域名下访问。