跨域请求如何携带cookie--案例解析

389 阅读2分钟

了解跨域

跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制。

简单理解:协议域名端口号全部相同,即为同源,同源请求不存在跨域;三者有其一不同,即为跨域。

搭建服务

安装express

npm install -g express

搭建第一个服务,并配置端口号1001

// app1.js

let express = require("express");
let colors = require("colors");

let app = express();
app.get("/login",(req, res)=>{
    res.cookie("sidd", "000000001");
    res.json({code:0, message:"one_on_one success"});
});
app.get("/getSid",(req, res)=>{
    const sid = req.headers.cookie.split("=")[1];
    res.json({code:0, sid});
});

app.use(express.static("./"));
app.listen(1001, ()=>{
    console.log(colors.green("app1 running at port:1001"));
});

搭建第二个服务,并配置端口1002

// app2.js

let express = require("express");
let colors = require("colors");

let app = express();
app.get("/cross_get",(req, res)=>{
    res.json({code:0, message:"1002 port response succeed"});
});

app.listen(1002, ()=>{
    console.log(colors.green("app2 running at port:1002"));
});

创建index.html,并创建俩按钮。

<!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">
    <title>Document</title>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

</head>
<body>
    <div>
        <button id="same">发送同域请求</button>
        <button id="diff">发送跨域请求</button>
    </div>
    <script src="./index.js"></script>
</body>
</html>

效果如下:

image.png

编写运行脚本

// index.js
axios.get("/login").then(function(data){
    console.log(data);
}).catch(function(){
    console.log("login报错");
});

document.querySelector("#same").onclick = function(){
    axios.get("/getSid").then(function(data){
        console.log(data);
    }).catch(function(){
        console.log("login报错");
    });
};

document.querySelector("#diff").onclick = function(){
    axios({
        method: "get",
        url: "http://localhost:1002/cross_get"
    }).then(function(res){
        console.log(res.data);
    }).catch(function(){
        console.log("cross error");
    });
};

目录结构如下

image.png

点击发送同域请求按钮

结果正常: image.png

点击发送跨域请求按钮

结果报错: image.png

解决方案

1、请求时配置withCredentials: true
2、跨域请求的服务器配置相应参数:Access-Control-Allow-Origin:http://localhost:1001"Access-Control-Allow-Credentials:true

如下:

//index.js

axios({
    method: "get",
    withCredentials: true,  // 新增++++++++
    url: "http://localhost:1002/cross_get"
}).then(function(res){
    console.log(res.data);
}).catch(function(){
    console.log("cross error");
});
// app2.js

let app = express();
// 新增一下代码设置响应头参数 ++++++++++
app.all("*", (req, res, next) => {
    res.header("Access-Control-Allow-Origin", "http://localhost:1001");
    res.header("Access-Control-Allow-Credentials", "true");
    next();
});

点击发送跨域请求按钮

运行结果 image.png

总结

前端请求时在request对象中配置"withCredentials": true

服务端在responseheader中配置"Access-Control-Allow-Origin", "http://xxx:${port}";

服务端在responseheader中配置"Access-Control-Allow-Credentials", "true"