“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第4篇文章,点击查看活动详情”
为什么会产生跨域?
这是浏览器的同源策略,当一个前端项目向后端项目发请求,或者说这两个项目要进行通信的话,那么这两个项目的这三个地址都要相同即:协议号 和 域名 和 端口号 都相同,这样才符合浏览器的同源策略。
协议号 和 域名 和 端口号
https://( 协议号) www.juejin.cn (域名) :8080 (端口号) /userInfo( 路径),如果这三个有一个不相同就不符合跨域策略。
跨域通常发生在什么时候?
跨域通常发生在后端响应回来的数据,在浏览器接收到时被跨域机制拦截下来
同源策略
我们都知道同源策略是浏览器的策略,它限制的是客户端;因为这个策略限制浏览器接收到客户端响应回来的数据,所以它不影响服务器端;同源策略在浏览器上存在,而不存在服务器上,所以服务器之间的数据交互不存在同源策略;所以第三种解决方案就是:我们自己有一个后端,然后我们向目的后端进行数据交互请求数据,同时我们将自己的后端开启跨域,最后让前端向自己的后端请求数据。这样就通过自己的后端间接的获取到了目的后端的数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<title>Document</title>
</head>
<body>
<button id="btn">获取数据</button>
<script>
let btn = document.getElementById('btn')
btn.addEventListener('click', () => {
$.ajax({
url: 'http://localhost:3001',
data: {
name: 'bruce'
},
headers:{ // 为了告诉后端,你返回的响应头的类型应该是xxx
"Content-Type":"application/json;charset=utf-8"
},
method: 'get',
success(res) {
console.log(res);
}
})
})
</script>
</body>
</html>
自己的后端:
// 自己的后端
const http =require('http')
// 这个函数只有前端发了请求才会执行
const server= http.createServer((req,res)=>{ // http.createServer 就是启动创建一个后端服务
// 所以在这里后端要告诉浏览器,你不能开启跨域,就是在响应头里面加
res.writeHead(200,{ // 成功就返回 200 的状态码
"Access-Control-Allow-Origin":"*", // 允许所有的源向我发请求 就是配置一个白名单
"Access-Control-Allow-Methods":"GET,POST,PUT,OPTIONS",// 请求的发生
"Access-Control-Allow-Headers":"Content-Type", // 加了这行就是允许的请求头设置类型
})// 就是后端专门提供的一个写响应头的东西
// 自己的后端向别人的后端请求数据,
const proxyReq =http.request({
host:'127.0.0.1',
port:'3000',
path:'/',
method:'GET',
},proxyRes=>{
// console.log(proxyRes);
proxyRes.on('data',result=>{
console.log(result.toString()); // 这就是我们向别人服务器上面拿的数据
res.end(result.toString()) // 将拿到的数据返回给前端
})
}).end()
})
server.listen(3001,()=>{ //自己的后端的端口为3001
console.log('nodeProxy 我的项目已启动');
})
目的后端:
// 别人的后端
const Koa= require('koa')
const app=new Koa()
const main=(ctx,next)=>{
console.log(ctx.query.name);
ctx.body='hello world'
}
app.use(main)
app.listen(3000,()=>{ // 目的后端的端口为3000
console.log('nodeProxy项目已启动');
})