如何解决Angular应用通过script标签加载跨域Angular Element的main.js不显示问题
跨域加载Angular Element不显示的解决办法
1. 配置CORS允许跨域请求
localhost:4200的开发服务器得允许4201的跨域请求,不然就算脚本下载完成,组件注册也可能出问题。
- 打开4200项目的
angular.json,给dev-server添加CORS配置:"serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { "port": 4200, "allowedHosts": ["localhost:4201"], "headers": { "Access-Control-Allow-Origin": "http://localhost:4201" } } } - 重启4200的开发服务,确保响应头里包含
Access-Control-Allow-Origin。
2. 确保组件注册代码正确触发
跨域加载脚本时,组件注册可能因为异步时机问题没执行,或者被环境拦截。可以把注册逻辑暴露到全局,手动触发:
- 在4200项目的
main.ts里,调整注册代码,把注册方法挂到window对象上:import { createCustomElement } from '@angular/elements'; import { AppComponent } from './app/app.component'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { NgModule } from '@angular/core'; @NgModule({ declarations: [AppComponent], imports: [], providers: [], bootstrap: [] }) class AppModule {} platformBrowserDynamic().bootstrapModule(AppModule) .then((moduleRef) => { const AppElement = createCustomElement(AppComponent, { injector: moduleRef.injector }); // 把注册方法暴露到全局 (window as any).registerAppElement = () => { if (!customElements.get('app-component')) { customElements.define('app-component', AppElement); } }; // 先自动尝试注册 (window as any).registerAppElement(); }) .catch(err => console.error(err)); - 在4201的index.html里,给script标签加onload回调,确保脚本加载完成后再执行注册:
<script src="http://localhost:4200/main.js" onload="registerAppElement()"></script> <!-- 标签名要和你定义的组件名完全一致 --> <app-component></app-component>
3. 解决Zone.js冲突问题
如果4201项目本身也加载了Zone.js,两个Zone.js实例会产生冲突,导致组件渲染失败:
- 最简单的处理方式是让4200的Angular Element不加载Zone.js:打开4200项目的
polyfills.ts,注释掉Zone.js的导入:// import 'zone.js'; // Included with Angular CLI. - 要是4201项目必须使用Zone.js,需要确保先加载4200的main.js,再加载4201的Zone.js,不过优先推荐前者方案。
4. 检查组件标签名是否匹配
确认4201的index.html里使用的标签名,和4200项目中customElements.define的第一个参数完全一致,比如注册的是app-root就不能写app-component。
内容的提问来源于stack exchange,提问作者Ramya Balasubramanian
相关产品推荐
相关产品推荐

