Node.js原生服务如何禁止直接访问静态文件并正常渲染页面?
解决方案
要实现禁止直接访问静态资源文件,但允许主页正常加载样式和脚本,核心思路是靠**请求来源(Referer 头)**区分直接访问和页面内资源加载请求。浏览器加载HTML里的CSS/JS时,会自动带上Referer头,指向当前页面的地址;而直接在地址栏输入资源URL时,Referer头要么为空,要么不包含你的服务器地址。
修改后的代码
const http = require('http'); const fs = require('fs'); const path = require('path'); const server = http.createServer((req, res) => { // 定义允许的静态资源路径 const allowedStaticPaths = ['/style.css', '/script.js']; const isStaticResource = allowedStaticPaths.includes(req.url); // 拦截直接访问静态资源的请求 if (isStaticResource) { const referer = req.headers.referer; // 检查请求是否来自当前服务器的主页 const isValidReferer = referer && new URL(referer).origin === `http://localhost:${PORT}`; if (!isValidReferer) { res.statusCode = 403; return res.end('Forbidden: Direct access not allowed'); } } // 映射请求到对应文件路径 let filePath; if (req.url === '/') { filePath = path.join(__dirname, 'public', 'index.html'); } else if (isStaticResource) { filePath = path.join(__dirname, 'public', req.url.slice(1)); // 去掉URL开头的斜杠 } else { // 其他未知路径直接返回404 res.statusCode = 404; return res.end('File not found'); } // 设置对应的内容类型 const extname = path.extname(filePath); let contentType = 'text/html'; if (extname === '.css') { contentType = 'text/css'; } else if (extname === '.js') { contentType = 'text/javascript'; } // 读取文件并返回响应 fs.readFile(filePath, (err, data) => { if (err) { if (err.code === 'ENOENT') { res.statusCode = 404; res.end('File not found'); } else { res.statusCode = 500; res.end('Internal Server Error'); } } else { res.setHeader('Content-Type', contentType); res.end(data); } }); }); const PORT = process.env.PORT || 3030; server.listen(PORT, () => { console.log(`Server running at http://localhost:${PORT}`); });
关键逻辑说明
- 静态资源白名单:用
allowedStaticPaths指定允许被页面加载的资源路径,避免其他无关文件被访问。 - Referer 校验:当请求是静态资源时,检查请求头里的
referer是否来自当前服务器。如果不是直接返回403禁止访问。 - 路径映射优化:只处理根路径和白名单内的静态资源请求,其他路径直接返回404,减少不必要的文件查找操作。
注意事项
- 如果部署到生产环境,记得把
localhost:${PORT}换成实际的域名,不然会因为环境变化导致验证失败。 - 虽然Referer头可能被部分浏览器或代理禁用,但在常规开发和大多数生产场景下,这个方法足够满足需求。
内容的提问来源于stack exchange,提问作者Yyuv Ali
相关产品推荐
相关产品推荐

