前后端分離項目的跨域及保持Session會話


當Web項目前后端分離開發的時候, 由於域名不一致, 會出現無法請求和無法維持會話的情況

 

OPTIONS

在前端Ajax請求后台的時候, 打開控制台可以看到, 每一次請求之前都會有一次OPTIONS類型的請求
OPTIONS稱為預檢請求, 通過這個請求, 瀏覽器會告知服務器,接下來的請求的情況

Access-Control-Request-Method: POST 
Access-Control-Request-Headers: X-PINGOTHER, Content-Type

  

 

得到服務器的回應后瀏覽器便知道這次請求是否被允許

 

OPTIONS的處理

后台可以在攔截器或過濾器中處理這個請求, 這里以Springboot后台的攔截器為例

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) {
    String method = request.getMethod().toLowerCase();
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, PATCH, DELETE");
    response.setHeader("Access-Control-Allow-Headers", "X-Requested-With,content-type");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Expose-Headers", "TK");
    if (method.equals("options")){
        return false;
    }
    //...
    return true;
}

  

 

Access-Control-Allow-Origin 代表允許請求源, 設置為*或設置為前端的域名即可解決跨域無法請求的問題例如http://domain
Access-Control-Allow-Methods 表示允許的請求方式

以下兩個特別說明
Access-Control-Allow-Headers 代表允許瀏覽器可以向 服務器發送哪些請求頭
Access-Control-Expose-Headers 代表允許瀏覽器可以讀取哪些服務器發送的請求頭
均限制在客戶端上

字由https://www.wode007.com/sites/73248.html 中國字體設計網https://www.wode007.com/sites/73245.html

利用Token保持會話

傳統開發前后端能維持會話, 是因為當服務器調用了HttpSession時, 會將SessionId放在請求頭的set-cookie中, 瀏覽器讀取到了這個信息, 就把SessionId保存在本地, 待下次請求時以Cookie的形式帶給服務器, 服務器根據收到的SessionId找到Session 以繼續會話

現在由於前后端分離后使用Cookie的種種不便, 可以換另一種方式來進行SessionId的傳輸, 就是把SessionId放在請求頭中帶給瀏覽器

接上一段代碼

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) {
    //...
    HttpSession session = request.getSession();
    response.setHeader("TK",session.getId());
    return true;
}

  

 

由於設置了response.setHeader("Access-Control-Expose-Headers", "TK");
表示客戶端可以讀取header中的TK字段, 客戶端就可以讀取放在TK中的SessionId保存到本地, 存儲方式可以是Cookie或者是LocalStorage都可以
當需要請求時用http://service;jsessionid=${token}的形式傳給服務器, 這個與傳統Web中Cookie:jsESSIONID=sessionid的形式效果是一致的
如此就達到了保持會話的目的了

 

為什么能維持會話

服務器根據sessionid保持會話這件事是容器完成的, 根據的就是請求中所傳來的URL后的;jsessionid= 或者 cookie中的jsESSIONID=,
容器根據sessionid自動找到內存中的Session。
這也是選擇;jsessionid=方式的原因。這會讓你沒有感覺像在做前后端分離的開發, 就像傳統的jsP開發一樣, 前后端融合在一起。

當然你也可以用其他方式手動操作, 比如直接傳參 http://service?JID=${token}, 在請求頭中帶過去之類的, 然后手動取得ID再去找對應的Session, 不過這就有點多此一舉了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM