You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 02:45:57