Express中res.send(data)引发浏览器下载文件而非渲染HTML页面问题
Hey there! Let's break down why your browser is downloading the HTML file instead of displaying it, and fix it up quickly.
The Root Cause
When you use fs.readFile() without specifying an encoding, it returns a Buffer object. When you pass this Buffer to res.send(), Express automatically sets the Content-Type response header to application/octet-stream—this MIME type tells browsers to treat the content as a downloadable file, not as HTML to render.
Fixes to Try
1. Use res.sendFile() (Recommended)
Express has a built-in method specifically for sending files, which handles MIME type detection and header setup automatically. This is the cleanest approach:
var express = require("express"); var app = express(); var path = require("path"); app.use('/node_modules', express.static('node_modules')); app.get("/", function (req,res) { const pathname = path.join(__dirname,"index.html"); // Use res.sendFile instead of manual fs.readFile res.sendFile(pathname, (err) => { if (err) { // Handle error gracefully instead of throwing res.status(500).send('Error loading index.html'); } }); }); app.listen("3000",function () { console.log("express server constructed"); })
2. Manually Set Content-Type (If You Need to Use fs.readFile)
If you still want to read the file manually, you have two options:
- Option A: Read the file as a string by specifying the
utf8encoding, then set the correct header:
var express = require("express"); var app = express(); var fs = require("fs"); var path = require("path"); app.use('/node_modules', express.static('node_modules')); app.get("/", function (req,res) { const pathname = path.join(__dirname,"index.html"); fs.readFile(pathname, 'utf8', function (err,data) { if(err){ res.status(500).send('Error loading index.html'); return; } res.setHeader('Content-Type', 'text/html'); res.send(data); }); }); app.listen("3000",function () { console.log("express server constructed"); })
- Option B: Keep the Buffer but set the
Content-Typeheader:
var express = require("express"); var app = express(); var fs = require("fs"); var path = require("path"); app.use('/node_modules', express.static('node_modules')); app.get("/", function (req,res) { const pathname = path.join(__dirname,"index.html"); fs.readFile(pathname,function (err,data) { if(err){ res.status(500).send('Error loading index.html'); return; } res.setHeader('Content-Type', 'text/html'); res.send(data); }); }); app.listen("3000",function () { console.log("express server constructed"); })
Why These Work
Setting Content-Type: text/html tells your browser that the response content is HTML, so it will render it as a webpage instead of triggering a download. res.sendFile() does this automatically by checking the file's extension (.html in this case) and setting the appropriate MIME type.
内容的提问来源于stack exchange,提问作者Chen Cheng

