同域策略是什么

同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个origin的资源进行交互。它是一个约定,也是浏览器核心也最基本的安全功能,它能帮助阻隔恶意文档,减少可能被攻击的媒介,提高安全性。同源策略会阻止一个域的javaScript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)。

跨域是什么
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同(不在一个源)就是跨域,就会有跨域问题。

跨域问题描述
前端开发阶段常会遇到跨域问题,主要原因是前后端分离导致的不在一个源,后端服务会存放在其他的服务器上而不是开发者的本地。如在开发过程中,本地打开一个页面url为http://127.0.0.1/index.html,访问接口为https://wj.hs.net/manageconsole-deploy/getCheckCode.json这个时候接口与页面的协议、域名、端口不同,就触发了跨域问题。

跨域报错,如下图:

判断跨域另一种方式:Option + 响应头

在正式跨域的复杂请求前,浏览器会根据需要,自动发起一个“PreFlight”(也就是Option请求,用来让服务端返回允许的方法(如get、post),被跨域访问的Origin(来源,或者域),还有是否需要Credentials(认证信息)。当在响应头中看到跨域属性就可判断接口跨域。服务端返回跨域响应头包含如下参数:

  1. Access-Control-Allow-Credentials: true 该项标志着请求当中是否包含cookies信息,只有一个可选值:true(必为小写)。如果 不包含cookies,请略去该项,而不是填写false。
  2. Access-Control-Allow-Headers: X-Requested-With, Content-Type, Authorization 用于 preflight request (预检请求)中,列出了将会在正式请求的 Access-Control-Request-Headers 字段中出现的首部信息。可支持的请求首部名字。请求头会列出所有支持的首部列表,用逗号隔开。
  3. Access-Control-Allow-Methods: OPTION, POST, GET, DELETE 在对 preflight request.(预检请求)的应答中明确了客户端所要访问的资源允许使用的方法或方法列表。
  4. Access-Control-Allow-Origin: http://127.0.0.2:3000 允许跨域的域名,只能填通配符或者单域名
  5. Access-Control-Max-Age: 用来指定本次预检请求的有效期(options),单位为秒,,在此期间不用发出另一条预检请求

解决方案

主要解决方案思路:通过本地代理服务,代理远程接口。

  1. 把存在跨域问题的接口写成调用本地域的接口,如当前打开页面为 http://127.0.0.1/index.html,将接口请求写为 http://127.0.0.1/api/getCheckCode.json
  2. 将接口转发到后端服务器地址。将1中的 http://127.0.0.1/api/getCheckCode.json转发为https://wj.hs.net/manageconsole-deploy/getCheckCode.json

以下提供2个解决方案:

Nginx代理

Nginx介绍
Nginx是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。我们处理跨域问题使用了nginx的http代理功能。

Nginx跨域代理操作

  1. 找到nginx.conf文件: 一般nginx.conf文件在nginx安装目录下的\conf\nginx.conf文件下;
  2. 在nginx.conf文件添加配置:

配置介绍:

  1. 监听80端口,将http://localhost的所有请求服务转发到http://127.0.0.1:81,实际访问页面http://127.0.0.1:81,打开页面的url为http://localhost
  2. http://localhost:80/api/user接口请求转发到 https://wj.hs.net/manageconsole-deploy/user

Webpack代理

Webpack介绍
Webpack是一个用于现代javaScript应用程序的静态模块打包器,和前端资源构建工具。在解决前端开发阶段的跨域问题,我们使用了webpack-dev-server的proxy属性。Webpack-dev-server是webpack官方提供的一个小型Express服务器。使用它可以为webpack打包生成的资源文件提供web服务,供开发调试使用。主要提供功能:为静态文件提供服务、自动刷新和热替换(HMR)。

Webpack-dev-server中的proxy提供了代理服务。

Webpack跨域代理操作

配置介绍:

1.target :表示/api/XXX会被代理到https://wj.hs.net/manageconsole-deploy/api/xxx',如:/api/user----> https://wj.hs.net/manageconsole-deploy/api/getCheckCode.json

  1. 处理跨域设置changeOrigin: true;
  2. pathRewrite:不想始终传递/api,则需要重写路径,如上请求/api/ getCheckCode.json会被代理到https://wj.hs.net/manageconsole-deploy/getCheckCode.json

实际开发遇到的chrome浏览器跨域问题

很多近期更新了chrome版本的同学会发现,本来可以访问的页面,在更新后页面刷不出来了,一般原因是在Chrome 80及以上版本中,Chrome会将没有声明SameSite值的cookie默认设置为SameSite=Lax,在跨域请求的情况下不允许跨域携带cookie给后端,导致所有跨域场景下使用cookie进行鉴权的服务会受到影响。

解决:

  1. 在chrome浏览器地址栏输入chrome://flags并回车;
  2. 在搜索栏中输入SameSite by default cookies搜索,并禁用如图中的两项设置 ,改为Disabled即可;

  1. 点击右下键ReLaunch重启浏览器即可。

总结

前端开发调试阶段遇到的跨域问题,主要是由于前后端服务不在同一个origin导致的,可以使用代理的方式解决。

以上提供了两种代理的方法:

  • nginx高性能的HTTP代理服务
  • webpack的webpack-dev-server插件中的proxy

排除以上同源策略导致的跨域问题,接口无报错,页面显示不正常情况,可以考虑是因为高版本chrome对跨域做了更多的限制导致的,可以设chrome://flags的SameSite。

跨域问题在前端开发阶段常会遇到,设置代理能够快速解决跨域问题,并不需要后端协助,节省了调试时间,提高开发效率。希望以上内容能够帮助到前端开发的同学们。

转载于:https://www.oschina.net/group/cross-front?circle=frontend

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。