
本文介绍一种基于 http accept 请求头的可靠方法,用于在服务端精准识别 .js 文件的访问场景:是被 <script> 标签引入、es 模块动态导入,还是用户直接在浏览器地址栏打开以查看源码,从而支持语法高亮、html 渲染等差异化响应。
本文介绍一种基于 http accept 请求头的可靠方法,用于在服务端精准识别 .js 文件的访问场景:是被 <script> 标签引入、es 模块动态导入,还是用户直接在浏览器地址栏打开以查看源码,从而支持语法高亮、html 渲染等差异化响应。
在构建现代前端开发工具链(如本地静态服务、代码预览服务或增强型 Service Worker)时,一个常见需求是:当用户双击打开一个 .js 文件(例如通过 file:// 协议或本地服务器路径 http://localhost:3000/script.js),希望自动为其生成带语法高亮的 HTML 页面;而当该文件被正常引入(如 <script src="script.js"></script> 或 import './script.js')时,则应原样返回纯 JavaScript 内容,不作任何 HTML 封装。
关键在于——浏览器在不同加载方式下会发送语义明确的 Accept 请求头,这是最稳定、无需客户端 JS 干预、且兼容所有现代浏览器的服务端判别依据:
✅ 作为脚本加载(<script> / import / fetch()):
Accept: */*
(浏览器明确表示可接受任意类型,不偏好 HTML)✅ 在新标签页中直接打开(即“查看源码”行为):
Accept: text/html,application/xhtml+xml,...
(浏览器明确声明优先接受 text/html,这是渲染页面的前提信号)
因此,服务端只需检查请求头中 Accept 是否包含 text/html 子串即可准确判断:
// Node.js + Express 示例
app.get('/scripts/:filename.js', (req, res) => {
const isViewedAsPage = req.headers.accept?.includes('text/html');
if (isViewedAsPage) {
// 读取原始 JS 内容,用 highlight.js 或 Prism 渲染为 HTML
const jsContent = fs.readFileSync(`./scripts/${req.params.filename}.js`, 'utf8');
const highlightedHtml = highlightJs.highlight(jsContent, { language: 'javascript' }).value;
res.send(`
<!DOCTYPE html>
<html><head><title>${req.params.filename}.js</title>
<style>pre { padding: 1rem; background: #f5f5f5; }</style>
</head>
<body><pre><code>${highlightedHtml}</code></pre></body>
</html>
`);
} else {
// 正常返回 JS 文件,确保 Content-Type 正确
res.type('application/javascript').sendFile(`./scripts/${req.params.filename}.js`);
}
});⚠️ 注意事项与最佳实践:
立即学习“Java免费学习笔记(深入)”;
- 不要依赖 User-Agent、Referer 或客户端 JS 检测(如 document.currentScript),它们不可靠或根本不可用(如模块加载、Worker 环境);
- 避免仅匹配 Accept: text/html 全值——实际值通常为逗号分隔的 MIME 列表,应使用 .includes('text/html') 或正则 /text\/html/;
- 若使用 Nginx / Apache,也可通过 map 或 RewriteCond 实现类似逻辑,无需改写应用层;
- 对于 file:// 协议,因无 HTTP 头,此法不适用;此时需结合 Service Worker 的 fetch 事件 + request.destination(但 destination 在直接打开时为 '',而脚本加载时为 'script' 或 'module'),作为补充方案;
- 始终显式设置 Content-Type:HTML 响应用 text/html,JS 响应用 application/javascript,避免 MIME 类型混淆导致执行异常或安全拦截。
综上,利用 Accept 请求头语义是当前最简洁、标准、跨环境兼容的服务端检测方案。它让开发者能优雅地实现“一文件两用”:既是可执行脚本,又是可阅读文档,大幅提升本地开发与代码分享体验。










