日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

面试官问:跨域请求如何携带cookie?

發(fā)布時(shí)間:2023/12/9 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试官问:跨域请求如何携带cookie? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

大家好,我是若?川。持續(xù)組織了6個(gè)月源碼共讀活動(dòng),感興趣的可以點(diǎn)此加我微信 ruochuan12?參與,每周大家一起學(xué)習(xí)200行左右的源碼,共同進(jìn)步。同時(shí)極力推薦訂閱我寫的《學(xué)習(xí)源碼整體架構(gòu)系列》?包含20余篇源碼文章。歷史面試系列

本文來自經(jīng)作者 @Ethan01 授權(quán)轉(zhuǎn)載
原標(biāo)題:面試題 -- 跨域請(qǐng)求如何攜帶cookie?
原鏈接:https://juejin.cn/post/7066420545327218725

前言

最近在參加面試找工作,陸陸續(xù)續(xù)的面了兩三家。其中面試官問到了一個(gè)問題:如何解決跨域問題?我巴巴拉拉的一頓說,大概了說了四種方法,然后面試官緊接著又問:那跨域請(qǐng)求怎么攜帶cookie呢?(常規(guī)的面試套路,一般都會(huì)順著你的回答往深了問)由于之前的項(xiàng)目都是同源的,不牽涉跨域訪問,所以一時(shí)沒有回答出來,后來研究了下,所以有了這篇文章。

閱讀本文,你將學(xué)到:

1.學(xué)會(huì)`withCredentials`屬性; 2.學(xué)會(huì)`axios`配置`withCredentials`; 3.學(xué)會(huì)設(shè)置`Access-Control-Allow-Origin`屬性; 4.學(xué)會(huì)設(shè)置`Access-Control-Allow-Credentials`屬性; 5.學(xué)會(huì)解決跨域請(qǐng)求攜帶源站cookie的問題;

一. 搭建一個(gè)跨域請(qǐng)求的環(huán)境

思路:

  • 使用express搭建第一個(gè)服務(wù)A(http://localhost:8000),運(yùn)行在8000端口上;

  • A服務(wù)托管index.html(用于在前端頁面發(fā)送網(wǎng)絡(luò)請(qǐng)求)文件;

  • 在A服務(wù)中寫一個(gè)處理請(qǐng)求的路由,加載index.html頁面時(shí),種下cookie(這里種cookie為了在請(qǐng)求B服務(wù)時(shí)攜帶上);

  • 使用express搭建第二個(gè)服務(wù)B(http://localhost:8003),運(yùn)行在8003端口上;

  • 在A服務(wù)托管的index.html頁面去請(qǐng)求B服務(wù),然后把cookie傳過去;

  • 先看下代碼結(jié)構(gòu),相對(duì)比較的簡單:

    image.png

    A服務(wù)的代碼:

    //?src/app1.js const?express?=?require("express"); const?app?=?express();//?`index.html`?加載時(shí)會(huì)請(qǐng)求login接口 //?設(shè)置`cookie` app.get("/login",?(req,?res)?=>?{res.cookie("user",?"jay",?{?maxAge:?2000000,?httpOnly:?true?});res.json({?code:?0,?message:?"登錄成功"?}); });//?此接口是檢測`cookie`是否設(shè)置成功,如果設(shè)置成功的話,瀏覽器會(huì)自動(dòng)攜帶上`cookie` app.get("/user",?(req,?res)?=>?{//?req.headers.cookie:?user=jayconst?user?=?req.headers.cookie.split("=")[1];res.json({?code:?0,?user?}); });//?托管`index.html`頁面 //?這樣的話在`index.html`中發(fā)起的請(qǐng)求,默認(rèn)的源就是`http://localhost:8000` //?然后再去請(qǐng)求`http://localhost:8003`就會(huì)出現(xiàn)跨域了 app.use("/static",?express.static("public"));app.listen("8000",?()?=>?{console.log("app1?running?at?port?8000"); });

    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></head><body><h2>this?is?index.html?at?port?8000</h2><button?id="button">發(fā)送同源請(qǐng)求</button><button?id="cross-button">發(fā)送跨域請(qǐng)求</button><script?src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>const?button?=?document.querySelector("#button");const?crossButton?=?document.querySelector("#cross-button");axios.get("http://localhost:8000/login",?{}).then((res)?=>?{console.log(res);});//?發(fā)送同域請(qǐng)求button.onclick?=?function?()?{axios.get("http://localhost:8000/user",?{}).then((res)?=>?{console.log(res);});};//?發(fā)送跨域請(qǐng)求crossButton.onclick?=?function?()?{axios({method:?"get",url:?"http://localhost:8003/anotherService",}).then((res)?=>?{console.log(res);});};</script></body> </html>

    B服務(wù)的代碼:

    //?src/app2.js const?express?=?require("express"); const?app?=?express();//?定義一個(gè)接口,index.html頁面請(qǐng)求這個(gè)接口就是跨域(因?yàn)槎丝诓煌?#xff09; app.get("/anotherService",?(req,?res)?=>?{res.json({?code:?0,?msg:?"這是8003端口返回的"?}); });app.listen("8003",?()?=>?{console.log("app2?running?at?port?8003"); });

    這個(gè)時(shí)候環(huán)境基本就搭建好了。

    二、解決跨域攜帶cookie問題

    首先我們先在A服務(wù)的index.html頁面中得到一個(gè)cookie,運(yùn)行A服務(wù):

    npm?install?express?-D node?src/app1.js

    然后打開http://localhost:8000/static/index.html: 沒有問題的話,頁面長這樣:

    image.png

    這個(gè)時(shí)候F12打開控制臺(tái):可以看到發(fā)送了一個(gè)login請(qǐng)求,并且設(shè)置了 cookie,也可以選擇瀏覽器控制臺(tái)的Application頁簽,選中cookie,可以看到cookie的信息:

    image.pngimage.png

    然后我們點(diǎn)擊頁面上的發(fā)送同源請(qǐng)求按鈕,可以看到發(fā)送了一個(gè) user 請(qǐng)求,并且已經(jīng)攜帶上了 cookie:

    image.png

    接下來刺激的畫面來了,我們點(diǎn)擊 發(fā)送跨域請(qǐng)求 按鈕,出現(xiàn)了跨域請(qǐng)求的報(bào)錯(cuò):

    image.png

    重點(diǎn):接下來開始解決跨域攜帶 cookie 問題:

    1. 在前端請(qǐng)求的時(shí)候設(shè)置 request 對(duì)象的屬性 withCredentials 為 true;

    什么是withCredentials?

    XMLHttpRequest.withCredentials 屬性是一個(gè)Boolean類型,它指示了是否該使用類似 cookies,authorization headers(頭部授權(quán))或者 TLS 客戶端證書這一類資格證書來創(chuàng)建一個(gè)跨站點(diǎn)訪問控制(cross-site?Access-Control)請(qǐng)求。在同一個(gè)站點(diǎn)下使用withCredentials屬性是無效的。

    如果在發(fā)送來自其他域的 XMLHttpRequest 請(qǐng)求之前,未設(shè)置withCredentials? 為 true,那么就不能為它自己的域設(shè)置 cookie 值。而通過設(shè)置withCredentials? 為 true 獲得的第三方 cookies,將會(huì)依舊享受同源策略,因此不能被通過document.cookie或者從頭部相應(yīng)請(qǐng)求的腳本等訪問。

    //?修改跨域請(qǐng)求的代碼 crossButton.onclick?=?function?()?{axios({withCredentials:?true,?//?++?新增method:?"get",url:?"http://localhost:8003/anotherService",}).then((res)?=>?{console.log(res);}); };

    這個(gè)時(shí)候再去發(fā)送一個(gè)跨域請(qǐng)求,你會(huì)發(fā)現(xiàn)依舊報(bào)錯(cuò),但是我們仔細(xì)看下報(bào)錯(cuò),意思是需要設(shè)置 header 的Access-Control-Allow-Origin屬性:

    image.png

    2. 在服務(wù)端設(shè)置Access-Control-Allow-Origin

    我們修改B(app2.js)服務(wù)的代碼:

    //?在所有路由前增加,可以攔截所有請(qǐng)求 app.all("*",?(req,?res,?next)?=>?{res.header("Access-Control-Allow-Origin",?"http://localhost:8000");next(); });

    修改完之后再次發(fā)送一個(gè)跨域請(qǐng)求,你會(huì)發(fā)現(xiàn),又報(bào)錯(cuò)了(接近崩潰),但是跟之前報(bào)的錯(cuò)不一樣了,意思大概就是Access-Control-Allow-Credentials這個(gè)屬性應(yīng)該設(shè)置為true,但是顯示得到的是個(gè)'':

    image.png

    3. 在服務(wù)端設(shè)置Access-Control-Allow-Credentials

    再次修改 B 服務(wù)的代碼(每次修改后需要重新運(yùn)行):

    //?在所有路由前增加,可以攔截所有請(qǐng)求 app.all("*",?(req,?res,?next)?=>?{res.header("Access-Control-Allow-Origin",?"http://localhost:8000");res.header("Access-Control-Allow-Credentials",?"true");?//?++?新增next(); });

    再發(fā)送一個(gè)跨域請(qǐng)求:

    image.pngimage.png

    可以看到,這個(gè)跨域請(qǐng)求已經(jīng)請(qǐng)求成功并且返回?cái)?shù)據(jù)了!而且也攜帶了A服務(wù)的cookie,這個(gè)時(shí)候已經(jīng)大功告成了。

    三、總結(jié)

  • 前端請(qǐng)求時(shí)在request對(duì)象中配置"withCredentials": true;

  • 服務(wù)端在response的header中配置"Access-Control-Allow-Origin", "http://xxx:${port}";

  • 服務(wù)端在response的header中配置"Access-Control-Allow-Credentials", "true"

  • 如果看完這篇文章能夠幫助到你,請(qǐng)給個(gè)贊哦~

    ·················?若川簡介?·················

    你好,我是若川,畢業(yè)于江西高校。現(xiàn)在是一名前端開發(fā)“工程師”。寫有《學(xué)習(xí)源碼整體架構(gòu)系列》20余篇,在知乎、掘金收獲超百萬閱讀。
    從2014年起,每年都會(huì)寫一篇年度總結(jié),已經(jīng)寫了7篇,點(diǎn)擊查看年度總結(jié)。
    同時(shí),最近組織了源碼共讀活動(dòng),幫助3000+前端人學(xué)會(huì)看源碼。公眾號(hào)愿景:幫助5年內(nèi)前端人走向前列。

    識(shí)別方二維碼加我微信、拉你進(jìn)源碼共讀

    今日話題

    略。分享、收藏、點(diǎn)贊、在看我的文章就是對(duì)我最大的支持~

    總結(jié)

    以上是生活随笔為你收集整理的面试官问:跨域请求如何携带cookie?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。