Networking: fetch/XHR GETs can silently return stale cached responses — default HttpBaseProtocolFilter never sets CacheControl.ReadBehavior
メンテナーはふだん 2 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 74/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 静か
- 技術スタック
- cpp, react-native
- 領域
- api, networking
調査の方向性
vnext/Shared/Networking/RedirectHttpFilter.cpp から始め、designated constructor、そのデフォルトフィルターの構築、および CacheControl() の passthrough を確認します。次に、WinRTHttpResource.cpp が HttpClient をどのように構築するかを追跡し、Cache-Control のないレスポンスに対する fetch/XHR GETs の繰り返しで動作を検証します。デフォルトの GETs が古いキャッシュ済みレスポンスを暗黙的に返さなくなり、既存のリダイレクト動作が維持されれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Environment
- react-native-windows 0.83.2 (also present on
mainas of 2026-07-17), new architecture (Fabric, composition), Win32/HWND host - Windows 11 (WinINet/WinHTTP cache active)
- Reproduced in a production app against an authenticated JSON API
Steps to reproduce
- Have a backend endpoint that serves
GETresponses without aCache-Controlheader (very common for JSON APIs — many frameworks send none by default). - In a react-native-windows app,
fetch()that endpoint (anAuthorizationheader does not prevent the problem). - Change the data server-side (e.g. save an edit through a
POST/PUT), thenfetch()the sameGETURL again.
Expected
The second GET hits the network (or at least revalidates) and returns the updated data — matching the behavior of the same JS on React Native Android (OkHttp with no cache configured) and on browsers for heuristically-cacheable authenticated API responses.
Actual
The second GET returns the previous response body with an HTTP 200, with zero network I/O (confirmed: no request reaches the server). The OS HTTP cache (WinINet) answers the request using RFC 7234 heuristic caching, because nothing in the RNW networking stack opts out of cache reads. In our app this manifested as "saves silently revert": a screen re-fetched after a successful save and rendered the pre-save data.
Root cause
RedirectHttpFilter builds its inner filters as default-constructed HttpBaseProtocolFilters and only configures redirect/UI behavior — CacheControl().ReadBehavior is never set, so it stays at HttpCacheReadBehavior::Default, which permits serving cached entries without revalidation:
vnext/Shared/Networking/RedirectHttpFilter.cpp(currentmain):- Lines ~72–76:
RedirectHttpFilter(winrt::hstring defaultUserAgent)delegates withwinrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter{}twice — default filters, default cache behavior. - Lines ~42–60: the designated constructor sets
AllowAutoRedirect(false)andAllowUI(false)on both inner filters but never touchesCacheControl().
- Lines ~72–76:
- Consumed by
WinRTHttpResource(vnext/Shared/Networking/WinRTHttpResource.cpp), which builds theHttpClientused for all JSfetch/XHR traffic.
The class already implements CacheControl() passthrough (RedirectHttpFilter.cpp ~line 117), so the plumbing exists — nothing ever calls it.
Suggested fix
In the RedirectHttpFilter constructor (next to the AllowAutoRedirect(false) calls), set:
baseFilter.CacheControl().ReadBehavior(winrt::Windows::Web::Http::Filters::HttpCacheReadBehavior::NoCache);
on both inner filters, which aligns RNW with React Native Android (OkHttp is configured with no HTTP cache, so JS-visible fetch semantics match across platforms). If disabling cache reads by default is considered too aggressive, at minimum expose a configuration knob (e.g. via IHttpModuleProxy/HttpSettings or a ReactPropertyBag property) so apps can opt out of WinINet cache reads — today there is no way to do this from app code short of cache-busting every URL.
Workaround (what we ship today)
- Server: middleware adding
Cache-Control: no-storeon all API GET responses. - Client (Windows only): axios/fetch interceptor appending a
_ts=<Date.now()>query parameter to every GET to defeat the WinINet cache key.
Both are required for apps that cannot control every backend; neither should be necessary.
- 主要言語
- C++
- スター
- 17.4k
- フォーク
- 1.2k
- 平均マージ
- 3日 10分
- マージ済み PR(30日)
- 14
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
microsoft/react-native-windows のほかの issue
-
Fabric text is drawn with ClearType onto transparent composition surfaces, fringing thin glyphsオープンNeeds: Triage :mag:
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
microsoft/react-native-windows#16340 ·
メンテナーはふだん 2 日以内に返信
-
bug Needs: Triage :mag:
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
microsoft/react-native-windows#16321 · コメント 1 件 ·
メンテナーはふだん 2 日以内に返信
-
Single-line TextInput text is drawn below center and clipped on ARM64 (New Architecture)対応中かも @ryfow が 2 日前に担当しました。 オープンbug Needs: Triage :mag:
難易度 2/5 1〜3時間 初心者へのやさしさ 35/100
microsoft/react-native-windows#16481 ·
メンテナーはふだん 2 日以内に返信
-
bug Needs: Triage :mag:
難易度 3/5 1〜2日 初心者へのやさしさ 48/100
microsoft/react-native-windows#16479 ·
メンテナーはふだん 2 日以内に返信
-
Needs: Triage :mag:
難易度 5/5 1週間以上 初心者へのやさしさ 30/100
microsoft/react-native-windows#16442 · コメント 2 件 ·
メンテナーはふだん 2 日以内に返信
microsoft/react-native-windows の issue をすべて見る
似ている issue
-
ai_p1 comp-message-queues
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
ClickHouse/ClickHouse#125890 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
メンテナーはふだん 1 日以内に返信
-
bug
難易度 1/5 1時間未満 初心者へのやさしさ 78/100
yt-project/ewah_bool_utils#215 · コメント 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
redis/memtier_benchmark#642 ·
メンテナーはふだん 1 日以内に返信
-
Feature Request
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
sandboxie-plus/Sandboxie#5653 ·
メンテナーはふだん 1 日以内に返信