React項目中fetch實現(xiàn)跨域接收傳遞session的解決方案
本次項目使用了react框架,同時使用fetch取代ajax作為獲取接口數(shù)據(jù)的交互方法。本以為過程中應(yīng)該不會有什么磕絆,沒想到遇到了session丟失這個讓人甚是苦惱的問題。期間本想換種方法來對接接口,但轉(zhuǎn)念一想如果每次遇到問題都選擇逃避,那么以后的編碼之路只能越走越窄,所以還是決定堅持下去。好在經(jīng)過一整天的摸索,總算是成功攻克了這個難關(guān),下面就對這次問題的解決做個總結(jié)。
首先,為什么會出現(xiàn)postman接口調(diào)試正常而程序里fetch調(diào)用卻出現(xiàn)session丟失的問題?
回顧fetch本身的特性——默認情況下, fetch在服務(wù)端不會發(fā)送或接收任何 cookies!!
再來看session——當客戶端第一次請求服務(wù)器的時候,服務(wù)器生成一份session保存在服務(wù)端,將該數(shù)據(jù)(session)的id以cookie的形式傳遞給客戶端;以后的每次請求,瀏覽器都會自動的攜帶cookie來訪問服務(wù)器(session數(shù)據(jù)id)。
這就意味著fetch這種方法如果想要攜帶cookie,需要經(jīng)過特殊的處理——credentials: "include",代碼如下:
fetch("https://ip:端口/api/Values/GetVerifyCode", { method: "GET", credentials: 'include', mode: 'cors', headers: { 'Content-Type': 'application/json' } }).then(res => res.json()) .then(res => { if (res.code == 200) { //xxxxxxx } });
這里還涉及到前后臺分離時經(jīng)常遇到的跨域問題(mode: 'cors'),什么是跨域?瀏覽器從一個域名的網(wǎng)頁去請求另一個域名的資源時,域名、端口、協(xié)議任一不同,都是跨域。在前后端分離的模式下,前后端的域名是不一致的,此時就會發(fā)生跨域訪問問題。在請求的過程中我們要想回去數(shù)據(jù)一般都是post/get請求,所以..跨域問題就出現(xiàn)。這是出于瀏覽器的同源策略限制。(節(jié)選自https://zhuanlan.zhihu.com/p/425855609)
后臺以.netcore webapi為例,需要在Startup.cs里配置好Cors,代碼如下:
ConfigureServices里:
services.AddCors(options => { options.AddPolicy("any", builder => { builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader(); });//跨域請求 });
Configure里:
app.UseCors("any");//跨域請求
這里要注意的是如果你在服務(wù)器端的web.config里已經(jīng)配置過跨域相關(guān)參數(shù)了,這里在加的話程序運行時會報錯(”*,*”…意思就是重復(fù)配置跨域參數(shù)),要使用credentials: 'include',需要將上面的允許來自所有域的跨域請求訪問改為只允許特定域訪問,同時允許Credentials,如下:
services.AddCors(options => { options.AddPolicy("any", builder => { builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader(); });//跨域請求 });
本來進行到這里我以為問題已經(jīng)解決了,在本地調(diào)試OK的情況下發(fā)布接口,然后調(diào)用發(fā)布好的服務(wù)器接口,卻還是沒有獲取到想要的cookie。以驗證碼為例:一個fetch1生成驗證碼,并把它通過響應(yīng)標頭帶回來,之后另一個fetch2調(diào)接口時把之前帶回來的cookie再通過請求標頭傳到后臺進行校驗,打開控制臺發(fā)現(xiàn)fetch2的請求標頭并沒有cookie值,而fetch1的響應(yīng)標頭里也沒有Set-Cookie。
點開末尾的cookie才發(fā)現(xiàn)問題的所在:
這個SameSite是何許人也?
SameSite是瀏覽器請求中Set-Cookie響應(yīng)頭新增的一種屬性,它用來標明這個 cookie 是否是“同站 cookie”,同站 cookie 只能在本域名中使用的cookie,不能作為第三方 cookie。Chrome 51 開始,瀏覽器的 Cookie 新增加了一個SameSite屬性,用來防止 CSRF 攻擊和用戶追蹤。該屬性起初是由Google 起草的一份草案用來來改進 HTTP 協(xié)議的。Chrome 計劃將Lax變?yōu)槟J設(shè)置。這時,網(wǎng)站可以選擇顯式關(guān)閉SameSite屬性,將其設(shè)為None (對舊版瀏覽器無效,因為舊版瀏覽器沒有該值) 。不過,前提是必須同時設(shè)置Secure屬性(Cookie 只能通過 HTTPS 協(xié)議發(fā)送),否則無效。(節(jié)選自https://www.cnblogs.com/w821759016/p/14595832.html)
了解了這個,便可以很快地對Startup.cs里的services.AddSession做出調(diào)整,如下:
services.AddSession(options => { options.Cookie.Name = ".AdventureWorks.Session"; options.IdleTimeout = TimeSpan.FromSeconds(1800);//設(shè)置session的過期時間 options.Cookie.HttpOnly = true;//設(shè)置在瀏覽器不能通過js獲得該cookie的值 options.Cookie.SameSite = SameSiteMode.None; options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; options.Cookie.IsEssential = true; });
其中,SameSite設(shè)為None配合Secure設(shè)為SameAsRequest,但要注意這個只允許訪問的接口為https接口,另外將SameSite設(shè)置為了Unspecified瀏覽器則會使用默認值lax,是沒有效果的。
最后,將原先的http接口改為https,至于https認證所需的SSL證書怎么搞這里就不贅述了,將這些完成后再次嘗試調(diào)用發(fā)布好的接口,fetch1里的響應(yīng)標頭以及fetch2里的請求標頭就都能在控制臺看見了,問題解決!
到此這篇關(guān)于React項目中fetch實現(xiàn)跨域接收傳遞session的解決方案的文章就介紹到這了,更多相關(guān)react fetch跨域接收傳遞session內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React-hooks面試考察知識點匯總小結(jié)(推薦)
這篇文章主要介紹了React-hooks面試考察知識點匯總,Hook?使你在無需修改組件結(jié)構(gòu)的情況下復(fù)用狀態(tài)邏輯,本文結(jié)合示例代碼給大家介紹的非常詳細,需要的朋友可以參考下2022-10-10react以create-react-app為基礎(chǔ)創(chuàng)建項目
這篇文章主要介紹了react以create-react-app為基礎(chǔ)創(chuàng)建項目,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03ReactJS?應(yīng)用兼容ios9對標ie11解決方案
這篇文章主要為大家介紹了ReactJS?應(yīng)用兼容ios9對標ie11解決方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-01-01React?正確使用useCallback?useMemo的方式
這篇文章主要介紹了React?正確使用useCallback?useMemo的方式,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下2022-08-08react源碼層深入刨析babel解析jsx實現(xiàn)
同作為MVVM框架,React相比于Vue來講,上手更需要JavaScript功底深厚一些,本系列將閱讀React相關(guān)源碼,從jsx -> VDom -> RDOM等一些列的過程,將會在本系列中一一講解2022-10-10