此貼接上貼實踐解決跨域問題的三種方式剖析前端
今天繼續作個人schub項目的時候,遇到了苦惱我一天的問題,expresss-session沒有持久化,我在後端把登陸的狀態存在req的session裏,下次發post的時候再發請求的時候req.session裏面存的用戶的狀態的字段沒了。node
我上次用到express-session的時候仍是作得那個微博系統,先後端雜糅的項目(node+ejs),那時候就沒遇到這個問題,後來排查這個問題的時候,google 網上有關express-session的項目,發現這些項目全是先後端在一塊兒的架構,而後我就意識到一個問題,先後端在一塊兒域名和端口都是一致的,當先後端分離在本地調試的時候,我處理了不少跨域問題,那麼如今,是否是由跨域問題引發的。react
我本地打印調試了fetch發送的請求,(由於跨域每次請求發了一個option),發現每次的session都是新的,sessionId不一樣,那麼怎麼保持session會話一致呢。express
後來差文檔,發現:後端
對於跨域 XMLHttpRequest 或 Fetch 請求,瀏覽器不會發送身份憑證信息。若是要發送憑證信息,須要設置 XMLHttpRequest 的某個特殊標誌位。對於附帶身份憑證的請求,服務器不得設置 Access-Control-Allow-Origin 的值爲「*」。
用了Access-Control-Allow-Credentials: true,就不能設置Access-Control-Allow-Origin:'*'了。因此能夠設置,當A用戶進來的時候,咱們設置A用戶爲白名單就好,同理B用戶也是。也就是說,誰訪問就把誰的域設置爲白名單就能夠了。跨域
Access-Control-Allow-Origin: <origin> | *
因此個人處理通常是:promise
app.all('/*', (req, res, next) => { res.setHeader('Access-Control-Allow-Origin', req.headers && req.headers.origin ? req.headers.origin : '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Connection, User-Agent, Cookie, Authorization'); res.setHeader('Access-Control-Allow-Credentials', true); //post請求以前,會發送一個options的跨域請求 if (req.method === 'OPTIONS') { res.sendStatus(200); } else { next() } })
因爲前端react裏面請求是fetch發送的,fetch的原理就是xhr+promise,
那麼fetch確定也有這麼一個維持身份憑證的消息頭,
瀏覽器
看MDN:服務器
XMLHttpRequest.withCredentials 屬性是一個Boolean類型,它指示了是否該使用相似cookies,authorization headers(頭部受權)或者TLS客戶端證書這一類資格證書來建立一個跨站點訪問控制(cross-site Access-Control)請求。在同一個站點下使用withCredentials屬性是無效的。 此外,這個指示也會被用作響應中cookies 被忽視的標示。默認值是false。 若是在發送來自其餘域的XMLHttpRequest請求以前,未設置withCredentials 爲true,那麼就不能爲它本身的域設置cookie值。而經過設置withCredentials 爲true得到的第三方cookies,將會依舊享受同源策略,所以不能被經過document.cookie或者從頭部相應請求的腳本等訪問。
三點信息:
1.跨域訪問中,只有帶上withCredentials=true纔會容許跨域的請求中帶上本身cookie,(authorization)而cookie中是存有sessionId的,因此也是保持會話一致的前提。
2.同域名下的這個參數是無效的。
3.經過這種方法攜帶的cookie依然受同源策略的限制,咱們不能直接經過前端手段或者腳本訪問到改cookie。cookie
因此我在react前端把全部的fetch的options中加上
credentials: 'include',
便可。此時發現每次fetch請求的session是同一個了。