JavaScript调用fetch无回调,上传文件无法获取响应状态码怎么办?
Hey there! Let's break down how to solve your problem—getting that elusive HTTP status code (and ideally the response body) after a successful file upload. The root issue here is almost certainly missing proper request event handling or not using modern API patterns that support callbacks/promises. Here are the most reliable solutions based on common upload approaches:
1. Using XMLHttpRequest (XHR) – The Classic Approach
If you're using XHR for uploads, you might have forgotten to listen to the right events to capture the response. Here's a corrected, complete example that gives you access to status code and response body:
const fileInput = document.getElementById('your-file-input'); const file = fileInput.files[0]; const formData = new FormData(); formData.append('file', file); const xhr = new XMLHttpRequest(); xhr.open('POST', '/your-api-endpoint', true); // Keep async set to true // Listen for successful response xhr.addEventListener('load', function() { if (xhr.readyState === XMLHttpRequest.DONE) { // Get HTTP status code const statusCode = xhr.status; console.log('Upload status code:', statusCode); // Get response body (adjust parsing based on your API's response type) let responseBody; try { responseBody = JSON.parse(xhr.responseText); } catch (e) { responseBody = xhr.responseText; // Fallback to plain text if not JSON } console.log('Upload response:', responseBody); // Handle success/failure based on status if (statusCode >= 200 && statusCode < 300) { alert('Upload succeeded!'); } else { alert(`Upload failed with status ${statusCode}`); } } }); // Listen for errors or aborts xhr.addEventListener('error', function() { console.error('Upload failed due to network error'); }); xhr.addEventListener('abort', function() { console.error('Upload was aborted'); }); // Send the request xhr.send(formData);
Key points here:
- We're using the
loadevent to catch the completed request, not just relying onreadyStatechecks alone. - We explicitly parse the response body (with a fallback for non-JSON responses).
- We handle network errors and aborts separately for better error visibility.
2. Using Fetch API – Modern Promise-Based Approach
If you're using Fetch, remember that Fetch doesn't reject on HTTP error statuses (like 404 or 500) by default—you have to check the response.ok flag manually. Here's how to structure it properly:
const fileInput = document.getElementById('your-file-input'); const file = fileInput.files[0]; const formData = new FormData(); formData.append('file', file); fetch('/your-api-endpoint', { method: 'POST', body: formData }) .then(response => { // First, get the status code const statusCode = response.status; console.log('Upload status code:', statusCode); // Check if the request was successful (2xx status) if (!response.ok) { throw new Error(`HTTP error! Status: ${statusCode}`); } // Parse the response body (use .text() if your API returns plain text) return response.json(); }) .then(responseBody => { console.log('Upload response body:', responseBody); alert('Upload succeeded!'); }) .catch(error => { console.error('Upload failed:', error.message); alert('Upload failed. Check console for details.'); });
Key notes for Fetch:
- Always check
response.okto handle non-2xx statuses as errors. - Use
.json()or.text()to parse the response body—this returns a promise, so you need an extra.then()to access it. - The
.catch()block will catch network errors AND any errors you throw for non-success statuses.
Common Pitfalls to Check
- CORS Issues: If your frontend is on a different domain than the API, make sure the backend sets the correct CORS headers (like
Access-Control-Allow-Origin). Without these, browsers will block access to the response body even if the upload succeeds. - Async/Await Alternative: If you prefer async/await over
.then()chains, you can rewrite the Fetch example with async functions for cleaner code:async function uploadFile() { try { const fileInput = document.getElementById('your-file-input'); const file = fileInput.files[0]; const formData = new FormData(); formData.append('file', file); const response = await fetch('/your-api-endpoint', { method: 'POST', body: formData }); const statusCode = response.status; console.log('Status code:', statusCode); if (!response.ok) { throw new Error(`Status: ${statusCode}`); } const responseBody = await response.json(); console.log('Response:', responseBody); } catch (error) { console.error('Upload failed:', error); } }
With either of these approaches, you'll be able to reliably get the HTTP status code and response body, giving you full control over handling the upload result.
内容的提问来源于stack exchange,提问作者SubZeno

