iOS Safari下React Redux异步请求数据结构异常问题
Hey there! Let's dig into this iOS Safari issue with your Redux async action and fetch calls. I've run into similar quirks with Safari's handling of fetch responses before, so here are some common culprits and fixes to try:
Safari has a history of being stricter with JSON parsing than Chrome or Firefox, and it won't automatically throw errors for non-2xx HTTP status codes. Let's beef up your fetch handling to account for this:
export function fetchTransactions() { return (dispatch) => { dispatch(requestTransactions()); return fetch('/getTransactions', { method: 'GET', headers: { Accept: 'application/json', 'Content-Type': 'application/json', Cache: 'no-cache', }, credentials: 'same-origin', }) .then(response => { // Critical: Safari doesn't throw for 4xx/5xx statuses—check manually if (!response.ok) { throw new Error(`Request failed: ${response.status}`); } // Add error handling for malformed JSON (Safari hates trailing commas!) return response.json().catch(parseErr => { console.error('Safari JSON parse error:', parseErr); // Return a fallback to keep your app running return []; }); }) .then(data => { dispatch(receiveTransactions(data)); }) .catch(error => { dispatch(fetchTransactionsFailed(error)); }); }; }
- Always validate
response.okbefore parsing—Safari will happily try to parse error responses as JSON, leading to unexpected data structures. - Wrap
response.json()in a catch to handle cases where the server sends invalid JSON that other browsers might ignore.
Even with Cache: 'no-cache', Safari often ignores client-side cache directives for GET requests. Add these more explicit headers to your fetch call:
headers: { Accept: 'application/json', 'Content-Type': 'application/json', 'Cache-Control': 'no-cache, no-store, must-revalidate', Pragma: 'no-cache', Expires: '0', },
- These headers are the "nuclear option" to override Safari's default caching behavior. Also, make sure your server sends matching
Cache-Controlheaders with the response—Safari prioritizes server-side directives.
Your credentials: 'same-origin' should work, but Safari has strict cookie policies:
- Ensure your session cookies are marked with
SameSite=Lax(orSameSite=Noneif cross-origin) andSecureif you're using HTTPS. - Verify your server sends the
Access-Control-Allow-Credentials: trueheader if this is a cross-origin request (even same-origin can be picky in Safari).
- Enable Safari's Web Inspector (Preferences > Advanced > Show Develop menu) and check the Network tab. Look at the raw response from
/getTransactions—is the JSON structure different? Is theContent-Typeheader correctly set toapplication/json? - Add
console.logfor the raw response and parsed data—Safari's console might show warnings or errors other browsers hide. - Test a simplified fetch call (without Redux) to isolate if the issue is with Redux's async flow or Safari's fetch implementation.
You're using cross-fetch—make sure you're importing the polyfill correctly at the top of your entry file:
import 'cross-fetch/polyfill';
Older Safari versions (pre-10.1) have partial fetch support, so loading the polyfill early ensures consistent behavior.
If you can share more details about the specific "abnormal" behavior (like data being undefined, extra fields, or parsing errors), I can help narrow it down further!
内容的提问来源于stack exchange,提问作者Wolgan Ens

