文章目录
- 一、前后端协商配置
- 1.1 前端页面搭建
- 1.2后端服务器搭建
- 二、配置允许跨域浏览器
- 三、Chrome浏览器安装ModHeader插件
企业开发时会分开发环境、测试环境以及生产环境,但是有的企业开发只有真正发布到线上的生产环境的流程才会严格配置,有的项目开发环境或者测试环境中,前后端配置没有特别严格要求,就导致前端请求发送时返回错误信息。比如项目发送了一个跨域请求,该请求需要自动携带Cookie信息给服务器进行身份认证,但是浏览器对跨域的请求不会自动携带Cookie的数据,此时在生产环境中前后端配置正常该请求正常返回数据,但是在开发环境和测试环境中要求不严格,前后端没有配合设置好配置信息,导致请求无法自动携带Cookie信息返回失败的信息,以下有两种方法解决。
一、前后端协商配置
1.前端请求时在请求头中配置
"withCredentials": true
;2.服务端在响应头中配置
"Access-Control-Allow-Origin", "http://xxx:${port}"
;3.服务端在响应头中配置
"Access-Control-Allow-Credentials", "true"
以下通过express实现后端服务器,利用简单的html页面模拟一个跨域请求的环境进行解释(ps:用其他语言的参考上方三点进行配置,此处只做简单的模拟)
1.1 前端页面搭建
index.html
该页面由服务器app1托管,运行服务器后,浏览器输入localhost:3000
,显示该页面
<!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="button">同源请求</button>
<button id="crossButton">跨域请求</button>
</div>
<script>
const button = document.querySelector("#button");
const crossButton = document.querySelector("#crossButton");
axios.get("http://localhost:3001/login", {}).then((res) => {
console.log(res);
});
// 发送同域请求
button.onclick = function () {
axios.get("http://localhost:3001/getUser", {}).then((res) => {
console.log(res);
});
};
// 发送跨域请求
crossButton.onclick = function () {
axios({
withCredentials: true,
method: "get",
url: "http://localhost:3002/crossList",
}).then((res) => {
console.log(res);
});
};
</script>
</body>
</html>
1.2后端服务器搭建
app1.js
const express = require('express')
const app = express()
// 设置`cookie`
app.get("/login", (req, res) => {
res.cookie("JESSIONID", "10101001", { maxAge: 2000000, httpOnly: true });
res.json({ code: 200, message: "登录成功" });
});
// 检测浏览器是否会自动携带上`cookie`
app.get("/getUser", (req, res) => {
const user = req.headers.cookie.split("=")[1];
res.json({ code: 0, user });
});
// 静态资源在public目录下,托管`index.html`页面
/*
这样访问http://localhost:3001就是index.html搭建的页面,此时在index.html中发起的请求,
默认的源就是`http://localhost:3001`,然后再去请求`http://localhost:3002`就会出现跨域
*/
app.use("/", express.static("public"));
app.listen(3001, () => {
console.log(`Example app listening on port 3001`)
})
app2.js
const express = require('express')
const app = express()
const port = 3002
app.all("*", (req, res, next) => {
res.header("Access-Control-Allow-Origin", "http://localhost:3001");
res.header("Access-Control-Allow-Credentials", "true"); // ++
next();
});
// 定义一个跨域接口(因为端口不同)
app.get("/crossList", (req, res) => {
const user = req.headers.cookie.split("=")[1];
res.json({ code: 200, msg: "这是3002端口返回的" +user});
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
结果:
页面初始化,返回登录结果,浏览器中存储返回的Cookie信息
配置前,发送跨域请求返回失败信息
配置后,发送跨域请求返回需要的信息
参考文章:面试官问:跨域请求如何携带cookie?
二、配置允许跨域浏览器
如何配置可跨域的浏览器,看这里Chrome浏览器的跨域设置
配置完成后,可自动携带Cookie
三、Chrome浏览器安装ModHeader插件
此为一种特殊情况,公司在本地开发代码是登录项目时使用的是已经发布到开发环境的登录地址,本地开发无登录的入口,所以登录时转跳的也是已经部署后的开发环境,而不是本地开发时的页面,无法将Cookie信息存入,此事后就会需要使用可跨域的浏览器,并安装插件配合使用
ModHeader它可以用来自定义HTTP请求头或重写响应头,包含覆盖Chrome浏览器请求头的默认值。
此处已经下载好了直接用就可
链接:https://pan.baidu.com/s/1uoiAq1yBL4PbIrC284k6uw?pwd=9xhh
提取码:9xhh
在Chrome浏览器中,点击右上角三个点->扩展程序->管理扩展程序->将下载好的文件拖入扩展程序管理页面中
然后在浏览器右上角固定该插件,点击该插件选择+MOD就可配置请求头信息了,配置完成后,在允许跨域的浏览器中发送请求,当发送请求时会请求头会携带配置好的信息
参考文章:ModHeader插件使用说明