Angular 4调用外部链接JS文件函数报错:startNAmeNoReg未定义
解决Angular 4中调用外部JS函数报错的问题
我来帮你搞定这个报错!你遇到的ERROR ReferenceError: startNAmeNoReg is not defined,核心原因是外部脚本还没加载完成,你就提前调用了里面的函数——毕竟你给脚本加了async和defer,它是异步加载的,ngAfterViewInit执行的时候,那个startNAmeNoReg函数可能还没被浏览器解析注册呢。
下面给你两种靠谱的解决方案:
方案一:监听脚本加载完成事件
修改你动态创建脚本的代码,给脚本添加onload回调,确保脚本加载完成后再执行你的函数:
// 建议把脚本加载逻辑放在组件的初始化钩子(比如ngOnInit)里 ngOnInit() { const body = <HTMLDivElement> document.body; const script = document.createElement('script'); script.src = 'https://sase.wde.de/dedesa/name.file.js'; script.async = true; script.defer = true; script.type = 'text/javascript'; // 关键:脚本加载完成后再调用目标函数 script.onload = () => { this.loadFoo(); }; // 可选:处理脚本加载失败的情况 script.onerror = () => { console.error('Failed to load external script!'); }; body.appendChild(script); } // 把loadFoo改成组件的私有方法,不需要export default private loadFoo(): void { const lastname = "dedee"; const firstname = "dede"; const mail = "ede@dede.d"; const mdn = "55662"; const siteweb = "dede.html"; const token = "dededede"; const date = "2018-05-29 14:03:57"; const webPage = "dedesz"; startNAmeNoReg(lastname, firstname, mail, mdn, webPage, token, siteweb, date); startNAmePush(lastname, firstname, mail, mdn, webPage, token, siteweb, date); }
另外,TypeScript可能会提示startNAmeNoReg和startNAmePush未定义,你可以在组件文件顶部添加类型声明:
// 声明外部JS中的函数类型,避免TS报错 declare function startNAmeNoReg( lastname: string, firstname: string, mail: string, mdn: string, webPage: string, token: string, siteweb: string, date: string ): void; declare function startNAmePush( lastname: string, firstname: string, mail: string, mdn: string, webPage: string, token: string, siteweb: string, date: string ): void;
方案二:用Promise封装脚本加载(更符合Angular风格)
你可以把脚本加载逻辑封装成一个Promise,用async/await来处理异步流程,代码可读性更高:
async ngAfterViewInit() { try { // 等待脚本加载完成 await this.loadExternalScript('https://sase.wde.de/dedesa/name.file.js'); // 脚本加载成功后调用函数 this.loadFoo(); } catch (error) { console.error('Script loading failed:', error); } } // 封装脚本加载的工具方法 private loadExternalScript(url: string): Promise<void> { return new Promise((resolve, reject) => { const script = document.createElement('script'); script.src = url; script.onload = () => resolve(); script.onerror = () => reject(new Error(`Could not load script: ${url}`)); document.body.appendChild(script); }); } private loadFoo(): void { // 这里写你的函数调用逻辑,和方案一一致 const lastname = "dedee"; const firstname = "dede"; const mail = "ede@dede.d"; const mdn = "55662"; const siteweb = "dede.html"; const token = "dededede"; const date = "2018-05-29 14:03:57"; const webPage = "dedesz"; startNAmeNoReg(lastname, firstname, mail, mdn, webPage, token, siteweb, date); startNAmePush(lastname, firstname, mail, mdn, webPage, token, siteweb, date); }
额外提醒
- 确保外部脚本的URL是可正常访问的,没有跨域限制(如果是同域或者已经配置了CORS就没问题);
- 不要同时给脚本设置
async和defer,虽然浏览器会处理,但通常选一个就够了——async是加载完就执行,defer是等DOM解析完再执行,根据你的需求选就行。
内容的提问来源于stack exchange,提问作者Ghizlane Lotfi
相关产品推荐
相关产品推荐

