Node.js静态托管HTML时local src引用的资源无法加载如何解决
问题原因
你当前的Node服务没有区分不同的请求路径,无论收到浏览器的什么请求,都统一返回content-type: text/html的index.html内容:
- 你访问
localhost:3000时,服务返回index.html,浏览器能正常解析显示标题 - 浏览器解析html时发现
<img src="doggy.png">,会自动发起第二个GET /doggy.png请求,此时服务还是返回index.html的文本内容,浏览器无法将文本识别为图片,因此加载失败。直接本地打开html是因为浏览器直接读取本地文件系统的资源,不需要走服务端请求,所以可以正常显示。
可行解决方案
给你两种实现方案,按需选择即可:
方案1:原生Node.js实现静态资源处理
不需要引入第三方依赖,手动处理不同路径的资源请求和正确的响应头:
const http = require('http') const fs = require('fs') const path = require('path') const server = http.createServer((req, res) => { // 处理根路径请求,返回index.html if (req.url === '/') { res.writeHead(200, { 'content-type': 'text/html;charset=utf-8' }) fs.createReadStream('index.html').pipe(res) return } // 处理其他静态资源请求 const filePath = path.join(__dirname, req.url) // 判断文件是否存在 fs.access(filePath, fs.constants.F_OK, (err) => { if (err) { res.writeHead(404, { 'content-type': 'text/plain;charset=utf-8' }) res.end('资源不存在') return } // 根据文件后缀设置正确的content-type const ext = path.extname(filePath).toLowerCase() const mimeMap = { '.html': 'text/html;charset=utf-8', '.png': 'image/png', '.jpg': 'image/jpeg', '.js': 'application/javascript;charset=utf-8', '.css': 'text/css;charset=utf-8' } const contentType = mimeMap[ext] || 'application/octet-stream' res.writeHead(200, { 'content-type': contentType }) fs.createReadStream(filePath).pipe(res) }) }) server.listen(process.env.PORT || 3000)
配置完成后只要把所有静态资源(html、图片、js、css等)都放在和server.js同级的目录下即可正常访问。
方案2:使用Express框架简化开发
Express内置了静态资源托管中间件,代码更简洁,维护成本更低:
- 首先安装依赖:
npm install express
- 修改server.js代码:
const express = require('express') const app = express() const port = process.env.PORT || 3000 // 托管当前目录下的所有静态资源,直接自动处理路径、响应头 app.use(express.static(__dirname)) // 也可以只托管指定文件夹,比如所有静态资源放public文件夹,就写app.use(express.static(path.join(__dirname, 'public'))) app.listen(port, () => { console.log(`服务已启动,访问地址:http://localhost:${port}`) })
内容的提问来源于stack exchange,提问作者Finn_Lancaster
相关产品推荐
相关产品推荐

