使用Fetch API处理控制台网络错误及401授权异常问题
Great question! Let’s break down what’s going on with your 401 errors and cover actionable fixes to handle these scenarios cleanly.
First, let’s clarify why you’re seeing that 401 response:
- The server returns 401 (Unauthorized) when it doesn’t receive a valid
tokenin the request headers. This happens in three cases:- The
tokenheader exists but has an empty value (either becauselocalStoragehas noaccess_tokenor the stored value is an empty string). localStorage.getItem('access_token')returnsnull(no token was ever stored).- Even if you include the header, the token itself is invalid (though your scenario focuses on missing/empty tokens).
- The
Your current code has two key gaps:
- It sends the request to the server even when the token is missing/empty, which wastes network resources and delays error feedback for users.
- It treats all non-
okresponses the same way—you can’t distinguish a 401 from other errors like 404 or 500, so you can’t run targeted logic for unauthorized cases.
Let’s fix this step by step with practical code adjustments:
1. Validate the Token Before Sending the Request
Don’t bother sending a request if you know the token is missing or invalid upfront. This saves unnecessary network calls and lets you handle the error immediately:
// Fetch the token first const accessToken = localStorage.getItem('access_token'); // Check if token exists and isn't an empty string if (!accessToken) { handleTokenMissing(); } else { // Proceed with the fetch request only if token is valid fetch("http://httpstat.us/401", { method: 'GET', headers: { "Accept": "application/json", "Accept-Language": "en-US", "Content-Type": "application/json", "token": accessToken } }) .then(response => handleResponse(response)) .catch(error => console.error('Request failed:', error)); }
2. Handle 401 Responses Explicitly
When the server does return a 401 (maybe the token expired even though it existed), you need to run specific logic—like clearing invalid tokens and redirecting to login:
function handleResponse(response) { if (response.ok) { // No need for Promise.resolve()—response.json() is already a Promise return response.json(); } else if (response.status === 401) { // Handle unauthorized scenario specifically handleUnauthorized(); // Reject with a meaningful error for debugging return Promise.reject(new Error('Unauthorized: Invalid or missing token')); } else { // Handle other HTTP errors (404, 500, etc.) return Promise.reject(new Error(`Request failed with status ${response.status}`)); } }
3. Create Reusable Error Handling Functions
Extract common logic into functions to keep your code clean and consistent:
function handleTokenMissing() { alert('Please log in to access this resource'); localStorage.removeItem('access_token'); // Clear any stale empty token window.location.href = '/login'; // Redirect to login page } function handleUnauthorized() { alert('Your session has expired. Please log in again.'); localStorage.removeItem('access_token'); // Invalidate the invalid token window.location.href = '/login'; }
4. Bonus: Add Refresh Token Logic (If Applicable)
If your app uses refresh tokens to get new access tokens, you can extend the 401 handler to try refreshing the token before redirecting to login:
async function handleResponse(response) { if (response.ok) { return response.json(); } else if (response.status === 401) { const refreshToken = localStorage.getItem('refresh_token'); if (refreshToken) { // Try to get a new access token const refreshResponse = await fetch('/api/refresh-token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ refreshToken }) }); if (refreshResponse.ok) { const { newAccessToken } = await refreshResponse.json(); localStorage.setItem('access_token', newAccessToken); // Retry the original request with the new token return fetch(response.url, { ...originalRequestOptions, headers: { ...originalRequestOptions.headers, token: newAccessToken } }).then(handleResponse); } } // If refresh fails or no refresh token exists, proceed to login handleUnauthorized(); return Promise.reject(new Error('Unauthorized: Could not refresh token')); } else { return Promise.reject(new Error(`Request failed with status ${response.status}`)); } }
By implementing these changes, you’ll cover all your token-related 401 scenarios efficiently, improve user experience, and keep your code maintainable.
内容的提问来源于stack exchange,提问作者Shiva Sai

