diff --git a/packages/vite/src/client/client.ts b/packages/vite/src/client/client.ts index ed1cab3eb17c2e..0abf5bccef0944 100644 --- a/packages/vite/src/client/client.ts +++ b/packages/vite/src/client/client.ts @@ -321,6 +321,11 @@ async function waitForSuccessfulPing( try { await fetch(`${pingHostProtocol}://${hostAndPath}`, { mode: 'no-cors', + headers: { + // Custom headers won't be included in a request with no-cors so (ab)use one of the + // safelisted headers to identify the ping request + Accept: 'text/x-vite-ping', + }, }) return true } catch {} diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index 0831cd01fe3743..541372996c2f4b 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -608,6 +608,16 @@ export async function _createServer( // open in editor support middlewares.use('/__open-in-editor', launchEditorMiddleware()) + // ping request handler + // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...` + middlewares.use(function viteHMRPingMiddleware(req, res, next) { + if (req.headers['accept'] === 'text/x-vite-ping') { + res.writeHead(204).end() + } else { + next() + } + }) + // serve static files under /public // this applies before the transform middleware so that these files are served // as-is without transforms.