Angular 11部署后脚本重复插入head引发报错,求解决方法
解决Angular 11组件中重复插入营销脚本的问题
问题原因
- 开发模式双重检测:Angular开发模式下默认会运行两次变更检测,触发组件的
ngOnInit钩子执行两次,导致脚本重复插入;若生产环境未开启enableProdMode,也会出现此问题。 - 组件重复实例化:如果该组件在路由复用、多页面引用等场景下被多次实例化,每次实例化都会执行构造函数和
ngOnInit逻辑,进而重复插入脚本。
解决方法
1. 开启生产模式(部署必做)
在main.ts中确保调用enableProdMode(),生产环境下Angular会关闭双重检测,避免钩子重复执行:
import { enableProdMode } from '@angular/core'; import { environment } from './environments/environment'; if (environment.production) { enableProdMode(); }
2. 添加脚本前做存在性校验(核心修复)
修改组件代码,在创建脚本前先检查目标脚本是否已存在,从根源避免重复插入:
import { Component, OnInit, Renderer2, Inject } from '@angular/core'; import { DOCUMENT } from '@angular/common'; @Component({ selector: 'app-teamroom-apply', templateUrl: './teamroom-apply.component.html', styleUrls: ['./teamroom-apply.component.css'] }) export class TeamroomApplyComponent implements OnInit { constructor( private renderer2: Renderer2, @Inject(DOCUMENT) private _document ) { // 检查外部统计脚本是否已存在 const existingLogScript = this._document.getElementById('naver-wcs-log'); if (!existingLogScript) { const r = this.renderer2.createElement('script'); r.type = 'text/javascript'; r.id = 'naver-wcs-log'; // 给脚本添加唯一ID用于校验 r.src = '//wcs.naver.net/wcslog.js'; this.renderer2.appendChild(this._document.head, r); } } ngOnInit(): void { // 检查内联初始化脚本是否已存在,同时判断全局变量是否已初始化 const existingInitScript = this._document.getElementById('naver-wcs-init'); if (!existingInitScript && !window._nasa) { const s = this.renderer2.createElement('script'); s.type = 'text/javascript'; s.id = 'naver-wcs-init'; // 给内联脚本添加唯一ID s.text = ` var _nasa={}; if(window.wcs) _nasa["cnv"] = wcs.cnv("5","1"); `; this.renderer2.appendChild(this._document.head, s); } } }
3. 可选:全局脚本加载方案(适合全站点生效的脚本)
如果该营销脚本需要在整个网站生效,更推荐直接在index.html的<head>标签中添加脚本,省去组件内的重复判断逻辑:
<head> <!-- 其他头部内容 --> <script type="text/javascript" src="//wcs.naver.net/wcslog.js"></script> <script type="text/javascript"> var _nasa={}; if(window.wcs) _nasa["cnv"] = wcs.cnv("5","1"); </script> </head>
内容的提问来源于stack exchange,提问作者BrownLee
相关产品推荐
相关产品推荐

