1.为什么会出现跨域问题
浏览器基于安全性考虑(减少一些攻击发生的可能性)不允许非同源(
同源是指协议、域名、端口三者相同,即使两个不同的域名指向同一个ip地址也是非同源。主域名相同二级域名不同也为不同源例如 https://abc.com 与https//:www.abc.com
)请求发生。
其实虽然浏览器报错,但是实际请求已经到了后端层面,只是浏览器不允许,拦截了请求
2.解决方案
2.1 jsonp
利用js文件请求不受同源策略限制实现,但是只能发送get请求,并且需要后端配合实现,现在基本不使用这种手段
2.2 cors 常用
跨源资源共享标准新增了一组 HTTP 标头字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是
GET
以外的 HTTP 请求,或者搭配某些 MIME 类型的POST
请求),浏览器必须首先使用OPTIONS
方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨源请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(例如 Cookie 和 HTTP 认证相关数据)。
CORS 请求失败会产生错误,但是为了安全,在 JavaScript 代码层面无法获知到底具体是哪里出了问题。你只能查看浏览器的控制台以得知具体是哪里出现了错误。
后端配置请求头Access-Control-Allow-Origin 把当前域名添加到上面,则浏览器就能正常发送请求获得服务器返回结果
将请求分为简单请求与复杂请求
简单请求不会发送options预检请求,会直接请求 服务器,服务器允许则访问成功,不允许则失败
复杂请求会先发送预检请求,看服务器是否允许此次请求,允许发送真正请求,不允许则请求失败
2.3 代理
2.3.1反向代理(负载均衡)
通过nginx 在前端所在服务器加一个nginx对部分请求进行转发,相当于多了一层中间人在传话,前端工程跟nginx所在服务器一个域名就不会跨域了
反向代理 服务器对用户不可见,用户不清楚真正的访问服务器那一台
2.3.2正向代理(vpn)
正向代理就是在本地客户端建立一个拦截,对于部分请求从本地,直接连接到例如vpn对应的服务器,再由服务器发送真正的请求到真实请求服务器
正向代理,用户对服务器不可见,服务器并不知道当前的用户到底是谁
2.3.3 node
一些基于node的工程(例如nuxt)可以通过node进行一个代理转发,本质也是代理
3. 浏览器允许的一些跨域
3.1 js文件加载
jsonp的实现也是基于浏览器允许非同源的js资源加载的前提
3.2 css文件加载
3.3 new Image 创建对象
可以用来实现埋点,但是只能发送get请求,且不能与服务器进行数据上的双向交流,即只能 给服务器传递数据而不能服务器给浏览器返回数据