Networking: fetch/XHR GETs can silently return stale cached responses — default HttpBaseProtocolFilter never sets CacheControl.ReadBehavior
Maintainer thường phản hồi trong vòng 2 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 74/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Ít trao đổi
- Công nghệ
- cpp, react-native
- Lĩnh vực
- api, networking
Hướng nghiên cứu
Bắt đầu trong vnext/Shared/Networking/RedirectHttpFilter.cpp, xem xét designated constructor, việc xây dựng bộ lọc mặc định của nó và passthrough của CacheControl(). Sau đó, theo dõi cách WinRTHttpResource.cpp xây dựng HttpClient và kiểm tra hành vi bằng các fetch/XHR GETs lặp lại đối với các response không có Cache-Control. Hoàn tất khi các GET mặc định không còn âm thầm trả về các response cũ trong cache và hành vi redirect hiện có vẫn được giữ nguyên.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.
- Ngôn ngữ chính
- C++
- Star
- 17.4k
- Fork
- 1.2k
- Merge trung bình
- 2 ngày 23 giờ
- Pull request đã merge (30 ngày)
- 16
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của microsoft/react-native-windows
-
Fabric text is drawn with ClearType onto transparent composition surfaces, fringing thin glyphsĐang mởNeeds: Triage :mag:
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
microsoft/react-native-windows#16340 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
bug Needs: Triage :mag:
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
microsoft/react-native-windows#16321 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
bug Needs: Triage :mag:
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 48/100
microsoft/react-native-windows#16479 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Needs: Triage :mag:
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 30/100
microsoft/react-native-windows#16442 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Fabric: activating the window doesn't announce the window or the focused control to a screen readerĐang mởNeeds: Triage :mag:
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
microsoft/react-native-windows#16435 ·
Maintainer thường phản hồi trong vòng 2 ngày
Tất cả issue của microsoft/react-native-windows
Issue tương tự
-
bug
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 95/100
rocketride-org/rocketride-server#2705 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
ROCm/rocm-systems#13754 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
neutralinojs/neutralinojs#1861 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
raspberrypi/libpisp#80 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
nanoporetech/pod5-file-format#198 ·