Express路由配置引发text/html非text/event-stream错误排查
Alright, let's break down why you're seeing that annoying MIME type error and how to fix it.
What's Causing the Issue?
The root problem here is your app.all('*') catch-all route is catching every request—including the one from webpack-hot-middleware/client that's trying to connect to the /__webpack_hmr endpoint for hot reloading.
When that request gets redirected to /, your server sends back index.html (which has a text/html MIME type), but the EventSource client expects a text/event-stream response. That mismatch is exactly why you're getting the error.
Also, quick side note: You don't need res.end() after res.sendFile or res.redirect—those methods already handle ending the response for you, so adding it is redundant.
The Fix
We need to make sure the webpack hot reload endpoint is excluded from the catch-all redirect. Here's the adjusted server code, with explanations of key changes:
const http = require('http'); const express = require('express'); const bodyParser = require('body-parser'); const path = require('path'); const app = express(); const server = http.createServer(app); app.use(bodyParser.json()); // Serve static files first so requests for bundle.js are handled properly app.use(express.static(path.join(__dirname, 'public/build'))); // Root route handler (optional, since express.static will auto-serve index.html here) app.get('/', (req, res) => { res.sendFile('index.html', {root: path.join(__dirname, 'public/build')}); }); // Exclude webpack hot reload endpoint from catch-all redirect app.all('/__webpack_hmr', (req, res) => { // If you're using server-side webpack hot middleware, this route will be handled automatically // For now, this prevents the redirect and avoids the MIME type error res.status(200).end(); }); // Catch-all route for all other unmatched requests, redirect to home app.all('*', (req, res) => { console.log('triggered'); res.redirect('/'); }); server.listen(3000);
If you want to set up webpack hot middleware properly (to enable actual hot reloading), first install it:
npm install webpack-hot-middleware --save-dev
Then update your server code to include the middleware (assuming you have a webpack config file):
const http = require('http'); const express = require('express'); const bodyParser = require('body-parser'); const path = require('path'); const webpack = require('webpack'); const webpackHotMiddleware = require('webpack-hot-middleware'); const webpackConfig = require('./webpack.config.js'); // Adjust path to your config const app = express(); const server = http.createServer(app); const compiler = webpack(webpackConfig); app.use(bodyParser.json()); app.use(express.static(path.join(__dirname, 'public/build'))); // Add webpack hot middleware to handle /__webpack_hmr requests app.use(webpackHotMiddleware(compiler)); app.get('/', (req, res) => { res.sendFile('index.html', {root: path.join(__dirname, 'public/build')}); }); // Now the catch-all won't interfere with hot reload requests app.all('*', (req, res) => { console.log('triggered'); res.redirect('/'); }); server.listen(3000);
Additional Tips
- The
express.staticmiddleware automatically servesindex.htmlwhen you hit the root route, so yourapp.get('/')handler is technically optional—but it doesn't hurt to keep it for explicit control. - When you removed the catch-all route earlier, the
/__webpack_hmrrequest wasn't redirected anymore, which is why the MIME error disappeared. By excluding this specific endpoint, we get to keep both the catch-all route for SPA routing and working hot reloading.
内容的提问来源于stack exchange,提问作者user9105234

