XMLHttpRequest初始请求Content-Type为HTML致404,延迟15秒恢复正常
Let’s break down what’s happening here and walk through how to fix it:
First, let’s recap your issue to align on the problem:
- Immediate or 3-second delayed
ajaxInitcalls return a 404 error, with the request’sContent-Typeincorrectly set to HTML instead of the expectedapplication/json - Requests delayed by 15 seconds work perfectly
- Replaying the failed requests via browser dev tools (Chrome’s Replay XHR, Firefox’s Edit and Replay) works without issues
Most Likely Root Causes
The biggest clue here is that replaying and delayed requests work—this points to timing-related variable initialization issues in your page, not a flaw in the XHR logic itself. Here’s what to prioritize checking:
1. Is serverPage properly initialized when early requests run?
Your ajaxInit function uses serverPage as the target endpoint URL. If this variable isn’t set to a valid server address when you first call ajaxInit (on page load or 3-second delay), the request will be sent to an invalid location, triggering a 404. By the 15-second mark, whatever script is responsible for setting serverPage has probably finished executing.
Fix/Check:
Add a console log at the start of ajaxInit to verify the URL value across requests:
function ajaxInit(urlId, query) { console.log("Target server URL:", serverPage); // Add this line var ajaxRequest = ajaxobj(); // ... rest of your code }
Compare the output from failed early requests vs the successful 15-second request. If serverPage is undefined or incorrect early on, ensure it’s defined before any ajaxInit calls run (e.g., move the serverPage definition to the top of your script, or wrap initial calls in a DOMContentLoaded listener).
2. Is formData fully populated when early requests run?
If formData is built from DOM elements (like form inputs), calling ajaxInit before the DOM is fully loaded means formData might be empty or malformed. This could cause your server to reject the request (return 404) because the payload doesn’t match expected route requirements.
Fix/Check:
Wrap your initial ajaxInit call in a DOMContentLoaded listener to ensure the page is fully ready before sending the first request:
document.addEventListener('DOMContentLoaded', function() { // Wait until the DOM is fully loaded before sending the first request ajaxInit("index", formData); });
Also, log formData right before passing it to ajaxInit to confirm it’s consistent across early and delayed requests.
Additional XHR Hardening Steps
Even if timing fixes the issue, let’s make your XHR code more robust to prevent similar problems in the future:
1. Add XHR Object Validation
Your ajaxobj function can return false if the XHR object fails to create, but your current code doesn’t handle this edge case. Add a check to avoid silent failures:
function ajaxInit(urlId, query) { var ajaxRequest = ajaxobj(); if (!ajaxRequest) { console.error("Failed to create XMLHttpRequest object"); return; } // ... rest of your code }
2. Explicitly Set the Accept Header
Adding an Accept header tells the server you expect JSON in response, which can help it route the request correctly and avoid unexpected 404s:
ajaxRequest.open("POST", serverPage, true); ajaxRequest.setRequestHeader("Content-type", "application/json;charset=UTF-8"); ajaxRequest.setRequestHeader("Accept", "application/json"); // Add this line ajaxRequest.send(JSON.stringify(serverData));
3. Validate the Request Payload
Log the stringified payload before sending to ensure it’s consistent across all requests:
var payload = JSON.stringify(serverData); console.log("Sending payload:", payload); ajaxRequest.send(payload);
Why Replaying Works
When you replay the request via dev tools, all your page’s variables (serverPage, formData) are already initialized correctly. The browser sends the exact payload and headers you defined, so the server accepts the request without issue.
内容的提问来源于stack exchange,提问作者Durgesh Satyam

