最简单方式是直接在中赋值window.app_config,适用于构建时已知的静态配置;需避免漏写window.前缀、使用let/const声明或this引用,并注意服务端注入时的xss防护、加载顺序及webpack对全局变量的识别处理。

script标签内直接赋值到window对象
最简单的方式是把配置写死在 <script></script> 标签里,直接挂到 window 上。适用于构建时已知、不随环境变化的配置(比如 API 基础路径、调试开关)。
常见错误是漏掉 window. 前缀,或用了 let/const 声明导致作用域隔离——它们不会自动成为全局变量。
- ✅ 正确写法:
<script> window.APP_CONFIG = { apiBase: "/api", debug: true, featureFlags: { payments: true } }; </script> - ❌ 错误写法:
const APP_CONFIG = {...}(仅限模块作用域) - ❌ 错误写法:
this.APP_CONFIG = {...}(this在非严格模式下指向window,但不可靠,尤其嵌套函数中易出错)
服务端渲染时注入JSON避免XSS风险
如果配置来自后端(如用户ID、权限列表),不能直接拼接 JS 字符串,否则可能触发 XSS。必须用 JSON.stringify() 序列化,并转义 HTML 特殊字符(如 、<code>&)。
Node.js + Express 示例中,常见坑是忘了对引号和反斜杠做双重转义,或没设 Content-Security-Policy 限制内联脚本。
- ✅ 安全写法(模板中):
<script> window.INITIAL_DATA = JSON.parse('<%= JSON.stringify(data).replace(/, '\u003c').replace(/&/g, '\u0026') %>'); </script>
- ⚠️ 注意:
JSON.stringify()输出的字符串本身不含 HTML 实体,所以替换必须在服务端完成;浏览器里用innerHTML解析再取值是危险的 - ⚠️ 如果用 Vue/React,推荐走 props 或 context 注入,而非依赖全局变量
多个script标签间共享配置的加载顺序问题
当配置脚本和业务脚本分属不同 <script></script> 标签时,顺序错乱会导致 undefined 错误。浏览器按 HTML 中出现顺序同步执行,但若配置脚本用了 async 或 defer,就破坏了这个前提。
- ✅ 必须保证配置脚本在所有依赖它的脚本之前,且不带
async或defer - ✅ 更稳妥的做法:把配置脚本放在
最顶部,业务脚本放底部 - ❌ 不要这样:
<script async src="app.js"></script>紧跟在配置脚本后——async不保证执行顺序 - ⚠️ 动态 import() 加载的模块无法访问同步注入的全局变量,除非显式传参或用
window查找
Webpack打包时如何保留运行时可覆盖的全局配置
Webpack 默认会把全局变量当作未声明的引用报错(ReferenceError: APP_CONFIG is not defined)。需要告诉它这是合法的外部变量。
关键点不是“怎么注入”,而是“怎么让打包器不干涉”。很多团队在这里卡住,以为要改 externals,其实只需配置 resolve.alias 或 ESLint 规则即可。
- ✅ Webpack 配置加:
module.exports = { resolve: { alias: { '@config': path.resolve(__dirname, 'src/config.js') } } };然后在代码里import config from '@config',比全局变量更可控 - ✅ ESLint 允许使用:
"globals": { "APP_CONFIG": "readonly" } - ⚠️ 别在 Webpack
externals里写APP_CONFIG——这会让打包器跳过它,但运行时仍需手动注入,反而增加耦合
window.xxx = ...,而是后续没人记得这个变量在哪定义、谁负责更新、有没有被其他脚本意外覆盖。越简单的方案,越需要明确约定和文档约束。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











