Offline.js网络连接监测异常咨询:WiFi热点关闭后的触发问题
Hey there, let's break down this Offline.js quirk you're hitting! The scenario where closing the WiFi hotspot (instead of the device's WiFi) breaks offline detection after 3+ attempts is super common, and it boils down to how Offline.js handles network checks and how browsers like Chrome behave in "connected but no internet" states. Here's how to fix it:
Offline.js defaults to checking static assets (like favicon.ico) which are often cached by browsers—even when you lose actual internet access, Chrome might serve the cached success response, tricking Offline.js into thinking you're still online. Fix this by switching to a dynamic health check endpoint and adjusting retry settings:
Offline.options = { checkOnLoad: true, interceptRequests: true, // Adjust retry logic to avoid hitting thresholds too fast reconnect: { initialDelay: 1000, delay: count => count * 2000, // Increment delay with each attempt maxDelay: 10000, attempts: Infinity // Remove hard retry limits, or set a higher number }, checks: { xhr: { url: '/api/health-check', // Use a server-side endpoint that returns 200 ONLY when online timeout: 5000, // Extend timeout to ensure we catch "no internet" timeouts method: 'GET' } } };
The key here is using a dynamic endpoint—your backend should return a clear 200 OK when the network and server are reachable, and an error (like 503 or 404) otherwise. No more cached false positives!
Chrome's navigator.onLine API can lie when you're connected to a hotspot with no internet (it says true because the WiFi connection exists, not because you have actual access). Add a fallback to manually verify connectivity even when the browser claims you're online:
// Force Offline.js to recheck when the browser fires online/offline events window.addEventListener('online', () => Offline.check()); window.addEventListener('offline', () => Offline.check()); // Add a periodic manual check to catch "connected but no internet" cases setInterval(() => { if (navigator.onLine) { // Fetch with no caching to get a real-time network status fetch('/api/health-check', { cache: 'no-store' }) .then(res => { if (!res.ok) throw new Error('No actual internet access'); }) .catch(() => { // Manually trigger Offline.js's offline state if check fails Offline.trigger('down'); }); } }, 3000); // Check every 3 seconds—adjust as needed
Offline.js has a built-in reconnect:failed event that fires when it hits its retry limit. Use this to force a "down" state instead of letting detection hang:
Offline.on('reconnect:failed', () => { console.log('Reconnection attempts exhausted—forcing offline state'); Offline.trigger('down'); }); // Don't forget to hook into your core offline/online handlers Offline.on('down', () => { // Your offline UI/logic here (e.g., show a banner, pause syncs) }); Offline.on('up', () => { // Your online recovery logic here (e.g., hide banner, resume syncs) });
To confirm caching is the issue, open Chrome DevTools (F12), go to the Network tab, and check "Disable cache" (make sure "Preserve log" is off too). Test your hotspot-closing scenario again—if Offline.js works correctly now, you know the dynamic endpoint fix is the right long-term solution.
内容的提问来源于stack exchange,提问作者DCJones

