做视频开头的网站,wordpress安装到子目录,上海建设网站公司,wordpress物品展示大家好#xff0c;我是若川。持续组织了6个月源码共读活动#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与#xff0c;每周大家一起学习200行左右的源码#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列本文… 大家好我是若川。持续组织了6个月源码共读活动感兴趣的可以点此加我微信 ruochuan12 参与每周大家一起学习200行左右的源码共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列本文来自经作者 Ethan01 授权转载原标题面试题 -- 跨域请求如何携带cookie?原链接https://juejin.cn/post/7066420545327218725前言最近在参加面试找工作陆陆续续的面了两三家。其中面试官问到了一个问题如何解决跨域问题我巴巴拉拉的一顿说大概了说了四种方法然后面试官紧接着又问那跨域请求怎么携带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传过去先看下代码结构相对比较的简单image.pngA服务的代码// 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: userjayconst 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的代码!DOCTYPE html
html langenheadmeta charsetUTF-8 /meta http-equivX-UA-Compatible contentIEedge /meta nameviewport contentwidthdevice-width, initial-scale1.0 /titleDocument/title/headbodyh2this is index.html at port 8000/h2button idbutton发送同源请求/buttonbutton idcross-button发送跨域请求/buttonscript srchttps://cdn.jsdelivr.net/npm/axios/dist/axios.min.js/scriptscriptconst 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);});};/script/body
/htmlB服务的代码// 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: 没有问题的话页面长这样image.png这个时候F12打开控制台可以看到发送了一个login请求并且设置了 cookie,也可以选择浏览器控制台的Application页签选中cookie可以看到cookie的信息image.pngimage.png然后我们点击页面上的发送同源请求按钮可以看到发送了一个 user 请求并且已经携带上了 cookieimage.png接下来刺激的画面来了我们点击 发送跨域请求 按钮出现了跨域请求的报错image.png重点接下来开始解决跨域携带 cookie 问题1. 在前端请求的时候设置 request 对象的属性 withCredentials 为 true;什么是withCredentialsXMLHttpRequest.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属性image.png2. 在服务端设置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但是显示得到的是个image.png3. 在服务端设置Access-Control-Allow-Credentials再次修改 B 服务的代码每次修改后需要重新运行// 在所有路由前增加可以拦截所有请求
app.all(*, (req, res, next) {res.header(Access-Control-Allow-Origin, http://localhost:8000);res.header(Access-Control-Allow-Credentials, true); // 新增next();
});再发送一个跨域请求image.pngimage.png可以看到这个跨域请求已经请求成功并且返回数据了而且也携带了A服务的cookie这个时候已经大功告成了。三、总结前端请求时在request对象中配置withCredentials: true服务端在response的header中配置Access-Control-Allow-Origin, http://xxx:${port};服务端在response的header中配置Access-Control-Allow-Credentials, true如果看完这篇文章能够帮助到你请给个赞哦~················· 若川简介 ·················你好我是若川毕业于江西高校。现在是一名前端开发“工程师”。写有《学习源码整体架构系列》20余篇在知乎、掘金收获超百万阅读。从2014年起每年都会写一篇年度总结已经写了7篇点击查看年度总结。同时最近组织了源码共读活动帮助3000前端人学会看源码。公众号愿景帮助5年内前端人走向前列。识别上方二维码加我微信、拉你进源码共读群今日话题略。分享、收藏、点赞、在看我的文章就是对我最大的支持~