我们在写前后端分离的项目时,数据要通过前端页面发送请求接口返回拿到数据后然后渲染到页面上的,在这时如果前端页面所在的服务器和后端的接口服务器不同源的话,就会出现跨域问题,比如这样。
因为前端页面服务跑在5500端口上,去请求没有经过跨域处理的服务端口为80的接口服务器时,因为端口不同受浏览器同源策略的影响,浏览器会阻止非同源的请求。
同源策略:
- 协议
- 主机
- 端口
只要两个服务器满足以上任意一个条件,那么这两个服务器即非同源,默认情况下浏览器会阻止非同源请求从而使前端页面拿不到数据。
实例解析:
一:
CORS(跨域资源共享)
当访问跨域的服务器时,浏览器会检查返回的http响应头
Access-Control-Allow-Origin: “允许被访问的源地址”
Access-Control-Allow-Methods: “允许的请求方法”
Access-Control-Allow-Headers: “允许携带的http请求头字段”
只有当前端页面所发的请求符合这些响应头字段的要求时,浏览器才允许访问成功,否则就会报访问80端口时的错误。
8083服务器设置cors响应头字段使能被跨域访问 ↓
二:nginx代理转发
nginx代理转发原理是同源策略只限制于浏览器端的服务器,当后端服务器访问后端服务器时即使是非同源也是可以正常访问的,所以我们构建一个8081端口的nginx服务器,并开启cors使得我们前端的5500端口可以访问该8081的服务器,然后再将请求转发给没有cors的80服务器(即 5500 -> 8081 -> 80)
开启8081的nginx服务并设置cors响应头 ↓
三:node自定义代理转发
实现原理和nginx差不多,只不过这个代理服务器是我们自己编写实现
自定义端口为8082的代理服务器,设置跨域cors响应头,请求转发给端口为80的无跨域处理服务器 ↓
四:jsonp方式
该跨域方式原理为script标签可以不受同源策略影响,前端页面定义回调函数并将该回调函数名作为请求url参数名,后端服务器将数据作为回调函数的实参包裹渲染给前端页面,此时触发前端页面的回调函数,形参即为后端传过来的数据
// jsonp跨域原理(通过script标签不受同源策略影响)
var script = document.createElement("script");
script.src = 'http://localhost:'+port+'/test?callback=getJsonpData';
document.body.appendChild(script);
script.onload = function () {
document.body.removeChild(script)
}
// jsonp方式回调函数
function getJsonpData(data) {
let port = document.querySelector('input').value
if(data){
let li = document.createElement('li')
li.textContent = (port ? port : '80') + ":" + data.messgae
document.querySelector("ul").appendChild(li)
}else{
let li = document.createElement('li')
li.textContent = (port ? port : '80') + ":" + "访问失败"
document.querySelector("ul").appendChild(li)
}
}
node端8084实现jsonp方式的服务器 ↓