“跨域”解决方案3--- node代理

574 阅读2分钟

“我报名参加金石计划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项目已启动');
})