您现在的位置是:亿华云 > 系统运维
面试官 -- 跨域请求如何携带 Cookie ?
亿华云2025-10-02 14:21:28【系统运维】5人已围观
简介前言 最近在参加面试找工作,陆陆续续的面了两三家。其中面试官问到了一个问题:如何解决跨域问题?我巴巴拉拉的一顿说,大概了说了四种方法,然后面试官紧接着又问:那跨域请求怎么携带cookie
前言
最近在参加面试找工作,面试陆陆续续的官跨面了两三家。其中面试官问到了一个问题:如何解决跨域问题?域请我巴巴拉拉的一顿说,大概了说了四种方法,求何然后面试官紧接着又问:那跨域请求怎么携带cookie呢?携带(常规的面试套路,一般都会顺着你的面试回答往深了问)由于之前的项目都是同源的,不牵涉跨域访问,官跨所以一时没有回答出来,域请后来研究了下,求何所以有了这篇文章。携带
阅读本文,面试你将学到:
1.学会`withCredentials`属性;
2.学会`axios`配置`withCredentials`;
3.学会设置`Access-Control-Allow-Origin`属性;
4.学会设置`Access-Control-Allow-Credentials`属性;
5.学会解决跨域请求携带源站cookie的官跨问题
一. 搭建一个跨域请求的环境
思路:
使用express搭建第一个服务A(http://localhost:8000),运行在8000端口上; A服务托管index.html(用于在前端页面发送网络请求)文件; 在A服务中写一个处理请求的域请路由,加载index.html页面时,求何种下cookie(这里种cookie为了在请求B服务时携带上); 使用express搭建第二个服务B(http://localhost:8003),携带运行在8003端口上; 在A服务托管的index.html页面去请求B服务,然后把cookie传过去;先看下代码结构,相对比较的简单:
A服务的代码:
// src/app1.js
const express = require("express");
const app = express();
// `index.html` 加载时会请求login接口
// 设置`cookie`
app.get("/login", (req, res) => {
res.cookie("user", "jay", { maxAge: 2000000, httpOnly: true });
res.json({ code: 0, message: "登录成功" });
});
// 此接口是检测`cookie`是否设置成功,如果设置成功的网站模板话,浏览器会自动携带上`cookie`
app.get("/user", (req, res) => {
// req.headers.cookie: user=jay
const user = req.headers.cookie.split("=")[1];
res.json({ code: 0, user });
});
// 托管`index.html`页面
// 这样的话在`index.html`中发起的请求,默认的源就是`http://localhost:8000`
// 然后再去请求`http://localhost:8003`就会出现跨域了
app.use("/static", express.static("public"));
app.listen("8000", () => {
console.log("app1 running at port 8000");
});index.html的代码:
this is index.html at port 8000
const button = document.querySelector("#button");
const crossButton = document.querySelector("#cross-button");
axios.get("http://localhost:8000/login", { }).then((res) => {
console.log(res);
});
// 发送同域请求
button.onclick = function () {
axios.get("http://localhost:8000/user", { }).then((res) => {
console.log(res);
});
};
// 发送跨域请求
crossButton.onclick = function () {
axios({
method: "get",
url: "http://localhost:8003/anotherService",
}).then((res) => {
console.log(res);
});
};
</html>B服务的代码:
// src/app2.js
const express = require("express");
const app = express();
// 定义一个接口,index.html页面请求这个接口就是跨域(因为端口不同)
app.get("/anotherService", (req, res) => {
res.json({ code: 0, msg: "这是8003端口返回的" });
});
app.listen("8003", () => {
console.log("app2 running at port 8003");
});这个时候环境基本就搭建好了。
二、解决跨域携带cookie问题
首先我们先在A服务的index.html页面中得到一个cookie,运行A服务:
npm install express -D
node src/app1.js然后打开http://localhost:8000/static/index.html: 没有问题的话,页面长这样:
这个时候F12打开控制台:可以看到发送了一个login请求,并且设置了cookie,也可以选择浏览器控制台的Application页签,选中cookie,可以看到cookie的信息:
然后我们点击页面上的发送同源请求按钮,可以看到发送了一个user请求,并且已经携带上了cookie:
接下来刺激的画面来了,我们点击 发送跨域请求 按钮,出现了跨域请求的报错:
重点:接下来开始解决跨域携带cookie问题:
1. 在前端请求的时候设置request对象的属性withCredentials为true;什么是withCredentials?
XMLHttpRequest.withCredentials 属性是服务器租用一个Boolean类型,它指示了是否该使用类似cookies,authorization headers(头部授权)或者TLS客户端证书这一类资格证书来创建一个跨站点访问控制(cross-site Access-Control)请求。在同一个站点下使用withCredentials属性是无效的。
如果在发送来自其他域的XMLHttpRequest请求之前,未设置withCredentials 为true,那么就不能为它自己的域设置cookie值。而通过设置withCredentials 为true获得的第三方cookies,将会依旧享受同源策略,因此不能被通过document.cookie或者从头部相应请求的脚本等访问。
// 修改跨域请求的代码
crossButton.onclick = function () {
axios({
withCredentials: true, // ++ 新增
method: "get",
url: "http://localhost:8003/anotherService",
}).then((res) => {
console.log(res);
});
};这个时候再去发送一个跨域请求,你会发现依旧报错,但是我们仔细看下报错,意思是需要设置header的Access-Control-Allow-Origin属性:
我们修改B(app2.js)服务的代码:
// 在所有路由前增加,可以拦截所有请求
app.all("*", (req, res, next) => {
res.header("Access-Control-Allow-Origin", "http://localhost:8000");
next();
});修改完之后再次发送一个跨域请求,你会发现,又报错了(接近崩溃),但是跟之前报的错不一样了,意思大概就是Access-Control-Allow-Credentials这个属性应该设置为true,源码下载但是显示得到的是个:
再次修改B服务的代码(每次修改后需要重新运行):
// 在所有路由前增加,可以拦截所有请求
app.all("*", (req, res, next) => {
res.header("Access-Control-Allow-Origin", "http://localhost:8000");
res.header("Access-Control-Allow-Credentials", "true"); // ++ 新增
next();
});再发送一个跨域请求:
可以看到,这个跨域请求已经请求成功并且返回数据了!而且也携带了A服务的cookie,这个时候已经大功告成了。
三、总结
前端请求时在request对象中配置"withCredentials": true; 服务端在response的header中配置"Access-Control-Allow-Origin", "http://xxx:${ port}"; 服务端在response的header中配置"Access-Control-Allow-Credentials", "true"如果看完这篇文章能够帮助到你,请给个赞哦!
很赞哦!(654)
上一篇: 数据中心现代化:升级旧数据中心以满足当前和未来的业务需求
下一篇: 数据中心整合优势有哪些?
相关文章
- 混合动力的主导地位为数据中心带来了新的关注
- 4、选择一个安全的域名注册商进行域名注册
- 打开https://www.aizhan.com/输入自己想要查询的域名然后按回车键,如果做过网站都会有数据显示出来
- 第六:这个圈子里的域名确实是赚钱的一些大玩家,至于小米农,有多少赚钱?几乎没有,也就是说,轿子里只有一个人,而且大多数人都抬着轿子。
- 量子数据中心可能是未来的发展方向
- 当投资者经过第二阶段的认真学习之后又充满了信心,认为自己可以在市场上叱咤风云地大干一场了。但没想到“看花容易绣花难”,由于对理论知识不会灵活运用.从而失去灵活应变的本能,就经常会出现小赢大亏的局面,结果往往仍以失败告终。这使投资者很是困惑和痛苦,不知该如何办,甚至开始怀疑这个市场是不是不适合自己。在这种情况下,有的人选择了放弃,但有的意志坚定者则决定做最后的尝试。
- 评估域名涉及的行业规模与发展状况成正比。
- 第五步:重复第四步,直到找到正确的纪录。
- 托管数据中心与私有数据中心:哪个更适合
- 打开https://www.aizhan.com/输入自己想要查询的域名然后按回车键,如果做过网站都会有数据显示出来
站长推荐
行业观察:万亿级IT服务市场未来之路将走向何方?
四、长串数字域名
因为域名解析需要同步到DNS根服务器,而DNS根服务器会不定时刷,只有DNS根服务器刷新后域名才能正常访问,新增解析一般会在10分钟左右生效,最长不会超过24小时,修改解析时间会稍微延长。
小白注册网站域名该怎么办?有什么步骤?
新型数据中心的建设及发展启示
为什么喜欢国外注册域名?国外注册域名注意什么?
为什么喜欢国外注册域名?国外注册域名注意什么?
用户邮箱的静态密码可能已被钓鱼和同一密码泄露。在没有收到安全警报的情况下,用户在适当的时间内不能更改密码。在此期间,攻击者可以随意输入帐户。启用辅助身份验证后,如果攻击者无法获取移动电话动态密码,他将无法进行身份验证。这样,除非用户的电子邮件密码和手机同时被盗,否则攻击者很难破解用户的邮箱。