跨域是个什么 ' 东 东 ' ?

953 阅读5分钟

前端开发过程跨域问题处理

跨域是由浏览器同源策略引起的,是指页面请求的接口地址,必须与页面url地址处于同域上(即域名,端口,协议相同)。这是为了防止某域名下的接口被其他域名下的网页非法调用,是浏览器对JavaScript施加的安全限制。

这个措施出发点是好的,但在项目开发的过程中,常常给前端开发者带来麻烦。由于页面开发中,静态资源是放在本地电脑上的,访问这些资源通常通过IP方式(127.0.0.1)或者localhosts来访问,与线上服务器所在域名不符,不能顺利进行接口调用。

何为同源策略

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

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

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

跨域.png

判断跨域另一种方式: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

跨域.png

以下提供两个解决方案

Nginx代理

Nginx介绍\

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

Nginx代理.png

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跨域代理操作

webpack代理.png

配置介绍:

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

总结

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

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

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

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

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