如何拦截mapbox-gl-js的HTTP响应并处理429状态码?
Hey Nicolas, I totally get where you're coming from—using the map's error event can feel frustrating when you need specific details like HTTP status codes from tile requests. The good news is Mapbox GL JS gives you a powerful tool to handle this exactly: the transformRequest option.
How it works
The transformRequest function lets you intercept every request the map makes, including tile requests to your custom tileserver. By overriding the default request handling, you can access the full HTTP response object, which includes the status code you need to check for 429s.
Example Implementation
Here's a practical code snippet that does exactly what you're asking for:
mapboxgl.accessToken = 'YOUR_ACCESS_TOKEN'; // Add a flag to avoid spamming modal popups let quotaAlertShown = false; const map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/streets-v12', // Or your custom style transformRequest: async (url, resourceType) => { // Only target tile requests (ignore fonts, sprites, etc.) if (resourceType === 'Tile') { try { const response = await fetch(url); // Check for 429 status code if (response.status === 429 && !quotaAlertShown) { quotaAlertShown = true; // Trigger your modal here—replace with your actual modal logic document.getElementById('quota-exhausted-modal').classList.add('active'); // Optional: Reset the flag after a cooldown to avoid permanent blocking setTimeout(() => { quotaAlertShown = false; }, 60000); // 1 minute cooldown } // Return the response data in a format Mapbox can use return { data: await response.blob(), headers: response.headers }; } catch (err) { // Handle other request errors if needed console.error('Tile request failed:', err); // Let Mapbox handle the error as usual return { url }; } } // Leave other request types (like style, sprites) as default return { url }; } });
Key Details to Note
- Target only tile requests: We check
resourceType === 'Tile'to avoid interfering with other map resources (like style JSON or sprites). - Prevent duplicate alerts: The
quotaAlertShownflag stops the modal from popping up every time a tile request fails with 429 (since multiple tiles might load at once). - Return valid response data: Mapbox needs the tile data as a
Blob, so we convert the fetch response to that format before returning it.
Why the error event falls short
The map's error event is designed to catch general loading failures, but it doesn't expose the raw HTTP response details. It only gives you a generic error message, which is why you couldn't get the 429 status code from it. transformRequest is the right tool for granular control over request handling.
内容的提问来源于stack exchange,提问作者Nicolas Bonnel

