一、同源策略和跨域问题
同源策略(Same Origin Policy)是一种约定,它是浏览器最核心也是最基本的安全功能。同源策略会阻止一个域的javascrip脚本和另一个域的内容进行交互,是用于隔离潜在恶意文件的关键安全机制;由于同源策略的存在带来的问题就是跨域问题。
在做前后端分离的项目中,前端和后端往往用的不是一个服务器,而浏览器在展示数据的时候,需要有同源检查,一般我们浏览器访问的动态数据来自于后端服务器tomcat(8080)端口,浏览器的静态数据来自于前端浏览器(与后端的端口不一样),这样就不会通过浏览器的同源检测。
上图中,浏览器网页的静态数据展示来源于请求8081端口,但是请求的动态数据来源于8080端口,就不能通过浏览器的同源检查,浏览器不会用8080响应的数据。
二、解决方法一:
如果请求的发送者和需要访问的资源在不同源的情况下,fetch 请求跨域 ,就会在请求中包含一个特殊的头(Origin),它会展示请求发送者的的源,也就是代表发请求的资源来自何处 (通过它就能辨别是否发生跨域 );目标资源通过返回 Access-Control-Allow-Origin 头 ,告诉浏览器允许哪些源使用此响应, 就限定了响应结果给谁用。
浏览器请求头:
在Java代码中的Controller层里面的具体方法上加一个@CrossOrigin注解
@CrossOrigin("http://localhost:8081")
加了之后再去看浏览器响应头就会包含Access-Control-Allow-Origin,并且会显示注解里面允许的内容。
三、解决方法二:
浏览器所有的请求都发给8081端口,由8081的代理去8080端口请求数据,8080就会将数据返回给8081端口,再由8081端口间接的将数据返回给浏览器,这时候对于浏览器来说,就没有发送跨域问题,它还是以为静态数据和动态数据都来自于8081端口。
首先需要安装代理的插件
npm install http-proxy-middleware --save-dev
然后在 express 服务器启动代码中将插件应用起来
import {createProxyMiddleware} from 'http-proxy-middleware'
还要去在 express 服务器启动代码中创建代理
app.use('/api', createProxyMiddleware({ target: 'http://localhost:8080', changeOrigin: true }));
// 'api'和'http://localhost:8080'根据自己的请求路径来定
意思是,访问当前前端端口的api所有请求的时候,都会走后面的代理,代理的请求会发给target指定的地址。
四、注意:
只要协议、主机、端口之一不同,就是不同源。
同源检查是浏览器的行为,而且只针对fetch、xhr请求。
如果是其他客户端,例如java http client、postman,它们都是不会做同源检查的。
通过表单提交、浏览器直接输入url地址这些方式发送的请求,也不会做同源检查。