React項目中fetch實現跨域接收傳遞session的解決方案

来源:https://www.cnblogs.com/mwx-sky/archive/2022/04/13/16140404.html
-Advertisement-
Play Games

本次項目使用了react框架,同時使用fetch取代ajax作為獲取介面數據的交互方法。本以為過程中應該不會有什麼磕絆,沒想到遇到了session丟失這個讓人甚是苦惱的問題。期間本想換種方法來對接介面,但轉念一想如果每次遇到問題都選擇逃避,那麼以後的編碼之路只能越走越窄,所以還是決定堅持下去。好在經 ...


  本次項目使用了react框架,同時使用fetch取代ajax作為獲取介面數據的交互方法。本以為過程中應該不會有什麼磕絆,沒想到遇到了session丟失這個讓人甚是苦惱的問題。期間本想換種方法來對接介面,但轉念一想如果每次遇到問題都選擇逃避,那麼以後的編碼之路只能越走越窄,所以還是決定堅持下去。好在經過一整天的摸索,總算是成功攻剋了這個難關,下麵就對這次問題的解決做個總結。

  首先,為什麼會出現postman介面調試正常而程式里fetch調用卻出現session丟失的問題?

  回顧fetch本身的特性——預設情況下, fetch在服務端不會發送或接收任何 cookies!!

  再來看session——當客戶端第一次請求伺服器的時候,伺服器生成一份session保存在服務端,將該數據(session)的id以cookie的形式傳遞給客戶端;以後的每次請求,瀏覽器都會自動的攜帶cookie來訪問伺服器(session數據id)。

  這就意味著fetch這種方法如果想要攜帶cookie,需要經過特殊的處理——credentials: "include",代碼如下:

 1 fetch("https://ip:埠/api/Values/GetVerifyCode", {
 2 
 3             method: "GET",
 4 
 5             credentials: 'include',
 6 
 7             mode: 'cors',
 8 
 9             headers: {
10 
11                 'Content-Type': 'application/json'
12 
13             }
14 
15         }).then(res => res.json())
16 
17             .then(res => {
18 
19                 if (res.code == 200) {
20 
21                     //xxxxxxx
22 
23                 }
24 
25             });

  這裡還涉及到前後臺分離時經常遇到的跨域問題(mode: 'cors'),什麼是跨域?瀏覽器從一個功能變數名稱的網頁去請求另一個功能變數名稱的資源時,功能變數名稱、埠、協議任一不同,都是跨域。在前後端分離的模式下,前後端的功能變數名稱是不一致的,此時就會發生跨域訪問問題。在請求的過程中我們要想回去數據一般都是post/get請求,所以..跨域問題就出現。這是出於瀏覽器的同源策略限制。(節選自https://zhuanlan.zhihu.com/p/425855609

  後臺以.netcore webapi為例,需要在Startup.cs里配置好Cors,代碼如下:

  ConfigureServices里:

 1 services.AddCors(options =>
 2 
 3             {
 4 
 5                 options.AddPolicy("any", builder =>
 6 
 7                 {
 8 
 9                     builder.AllowAnyOrigin()
10 
11                     .AllowAnyMethod()
12 
13                     .AllowAnyHeader();
14 
15                 });//跨域請求
16 
17             });

  Configure里:

1 app.UseCors("any");//跨域請求

  這裡要註意的是如果你在伺服器端的web.config里已經配置過跨域相關參數了,這裡在加的話程式運行時會報錯(”*,*”…意思就是重覆配置跨域參數),要使用credentials: 'include',需要將上面的允許來自所有域的跨域請求訪問改為只允許特定域訪問,同時允許Credentials,如下:

1 builder.WithOrigins("http://ip:埠", "http://localhost:3000")
2 
3                     .AllowAnyMethod()
4 
5                     .AllowAnyHeader()
6 
7                     .AllowCredentials();

  本來進行到這裡我以為問題已經解決了,在本地調試OK的情況下發佈介面,然後調用發佈好的伺服器介面,卻還是沒有獲取到想要的cookie。以驗證碼為例:一個fetch1生成驗證碼,並把它通過響應標頭帶回來,之後另一個fetch2調介面時把之前帶回來的cookie再通過請求標頭傳到後臺進行校驗,打開控制台發現fetch2的請求標頭並沒有cookie值,而fetch1的響應標頭裡也沒有Set-Cookie。

  點開末尾的cookie才發現問題的所在:

       

       

  這個SameSite是何許人也?

  SameSite是瀏覽器請求中Set-Cookie響應頭新增的一種屬性,它用來標明這個 cookie 是否是“同站 cookie”,同站 cookie 只能在本功能變數名稱中使用的cookie,不能作為第三方 cookie。Chrome 51 開始,瀏覽器的 Cookie 新增加了一個SameSite屬性,用來防止 CSRF 攻擊和用戶追蹤。該屬性起初是由Google 起草的一份草案用來來改進 HTTP 協議的。Chrome 計劃將Lax變為預設設置。這時,網站可以選擇顯式關閉SameSite屬性,將其設為None (對舊版瀏覽器無效,因為舊版瀏覽器沒有該值) 。不過,前提是必須同時設置Secure屬性(Cookie 只能通過 HTTPS 協議發送),否則無效。(節選自https://www.cnblogs.com/w821759016/p/14595832.html

  瞭解了這個,便可以很快地對Startup.cs里的services.AddSession做出調整,如下:

 1 services.AddSession(options =>
 2 
 3             {
 4 
 5                 options.Cookie.Name = ".AdventureWorks.Session";
 6 
 7                 options.IdleTimeout = TimeSpan.FromSeconds(1800);//設置session的過期時間
 8 
 9                 options.Cookie.HttpOnly = true;//設置在瀏覽器不能通過js獲得該cookie的值
10 
11                 options.Cookie.SameSite = SameSiteMode.None;
12 
13                 options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
14 
15                 options.Cookie.IsEssential = true;
16 
17             });

  其中,SameSite設為None配合Secure設為SameAsRequest,但要註意這個只允許訪問的介面為https介面,另外將SameSite設置為了Unspecified瀏覽器則會使用預設值lax,是沒有效果的。

  最後,將原先的http介面改為https,至於https認證所需的SSL證書怎麼搞這裡就不贅述了,將這些完成後再次嘗試調用發佈好的介面,fetch1里的響應標頭以及fetch2里的請求標頭就都能在控制台看見了,問題解決!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Drawable表示一種可繪製的內容,可以由圖片或者顏色組成.Android下的Drawable有BitmapDrawable、GradientDrawable、LayerDrawable等等 1.BitmapDrawable 它表示一張圖片,我們可以直接將圖片放在drawable目錄下,該圖片就可 ...
  • Handler是我們在開發中經常會接觸到的類,因為在Android中,子線程一般是不能更新UI的. 所以我們會使用Handler切換到主線程來更新UI,那Handler是如何做到實現不同線程之間的切換呢? 先看一個例子 1.ThreadLocal的簡單使用 public class HandlerA ...
  • 一、Bundle Android的Activity、Service、Receiver都支持在Intent傳遞Bundle數據,Bundle實現了Parcelable介面, 所以能很方便的在不同進程之間進行數據傳傳輸.比如A應用打開B應用的某個Activity,如果要傳遞自定義的類型, 可以繼承自Pa ...
  • 簡單開頭 首先技術面試官會根據簡歷里所寫的項目和個人掌握技術棧提問(我不知道已經改過多少次簡歷了,因為前期投簡歷是真的是沉在茫茫大海,撈漂流瓶都撈不到的那種) 我的技術棧:(Vue還在苦苦的自學當中,隨便推薦一下coderwhy老師B站的教學視頻,真的不錯,講得深入淺出,越聽越想聽)地址:https ...
  • 經過前面七天的學習,對Node.js開發已經有了一個初步的認識,今天繼續學習Node.js在web開發參數傳遞相關內容,僅供學習分享使用,如有不足之處,還請指正。 ...
  • Vue實戰-購物車案例 普通購物車 實現的功能:添加商品到購物車,計算總價 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>購物車</title> <script src="https://cdn.bootc ...
  • 首先,要先在這裡分享一下我的喜悅,從昨天開始其實一直都在喜悅當中的,我收到了我的第一份offer,這感覺不擺了,比第一桶金都還舒服,雖然我還沒收到第一桶金哈哈,不過offer都得了應該也快了。 今天的內容有點小多,容我慢慢道來 1. 首先我們看到包的管理配置文件以及下包慢的問題,在我們多人協作下,是 ...
  • element UI中table表格在選中數據後點擊分頁,再選中數據,回到第一頁後,原來選中的數據已經不再是勾選狀態了,現在要怎樣記住所有分頁中的勾選狀態呢?我這裡有比較簡便的方法。不需要緩存數據等複雜的方式。 1、首先在table標簽上定義row-key和ref標誌名稱。具體row-key等功效, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...