如何在Angular中访问Azure静态Web应用的应用设置修改环境变量?
结论
完全可以实现,但要先搞清楚一个前提:Angular 项目里默认的 environment.ts 是构建阶段就被编译进静态打包产物的,Azure 静态 Web 应用的 Application Settings 是运行时注入的配置,没法直接修改已经编译好的 js 里写死的 environment 值。只要做少量代码改造,把需要动态调整的参数改成运行时加载,就能实现改配置不用重新部署、直接切换API地址和Application Insights密钥的效果。
具体实现步骤
1. 拆分静态配置和动态配置
把不需要改动的配置继续留在 environment.ts 里,需要动态调整的两个参数单独拎出来做运行时配置:
- 在项目
src/assets目录下新建app-config.json,这个文件不会被webpack编译,构建后会原封不动作为静态资源存在:
{ "SERVER_API_URL": "https://backend01.azurewebsites.net", "APP_INSIGHTS_KEY": "<key>" }
- 确认
angular.json里的 build 配置已经把src/assets加入了 assets 数组,避免构建时这个文件被漏掉。
2. 加应用启动前的配置加载逻辑
- 新建配置服务
src/app/services/app-config.service.ts,用来全局存储运行时读到的配置:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class AppConfigService { SERVER_API_URL = ''; APP_INSIGHTS_KEY = ''; constructor(private http: HttpClient) {} // 应用初始化时调用,加载完配置才会启动页面 loadConfig(): Promise<void> { return this.http.get<Record<string, string>>('/assets/app-config.json') .toPromise() .then(res => { this.SERVER_API_URL = res.SERVER_API_URL; this.APP_INSIGHTS_KEY = res.APP_INSIGHTS_KEY; }); } }
- 在
app.module.ts里配置APP_INITIALIZER,保证配置在应用启动前就加载完成,避免出现页面发请求了还没拿到接口地址的问题:
import { APP_INITIALIZER, NgModule } from '@angular/core'; import { AppConfigService } from './services/app-config.service'; import { HttpClientModule } from '@angular/common/http'; @NgModule({ imports: [HttpClientModule], providers: [ { provide: APP_INITIALIZER, useFactory: (configService: AppConfigService) => () => configService.loadConfig(), deps: [AppConfigService], multi: true } ] }) export class AppModule {}
- 把项目里所有原来引用
environment.SERVER_API_URL和environment.appInsights.instrumentationKey的地方,全部替换成从AppConfigService里取对应的值即可。
3. 配置Azure侧的动态替换
这一步的核心是让Azure返回app-config.json的时候,自动用你在Application Settings里配的值覆盖文件里的默认值,不需要重新构建:
- 先在你截图的Application Settings页面,新增两个配置项:
- 键:
SERVER_API_URL,值填你需要切换的后端API地址 - 键:
APP_INSIGHTS_KEY,值填对应环境的Application Insights密钥
- 键:
- 在项目根目录新建
staticwebapp.config.json(Azure静态Web应用的路由配置文件),加一条路由重写规则,把访问配置文件的请求转到自带的托管函数:
{ "routes": [ { "route": "/assets/app-config.json", "rewrite": "/api/get-app-config" } ] }
- 利用Azure静态Web应用自带的免费托管API,在项目根目录的
api/get-app-config文件夹下新建一个简单的HTTP触发函数,读取环境变量返回配置即可,NodeJS版本示例代码:
module.exports = async function (context) { context.res = { headers: { 'Content-Type': 'application/json' }, body: { SERVER_API_URL: process.env.SERVER_API_URL, APP_INSIGHTS_KEY: process.env.APP_INSIGHTS_KEY } }; }
把这部分代码和主项目一起部署一次之后,后续你只需要在Portal的Application Settings里改这两个值,点保存等个几秒钟,刷新页面就能读到新的配置,完全不需要重新改代码构建部署。如果开了staging预发布环境,每个环境的应用设置是独立的,可以分别配不同的地址和密钥。
补充说明
- 第一次部署完这个改造之后,后续所有配置调整都不需要再动代码
- 不需要动态调整的参数(比如你配置里的
production、DEVELOPER_OPTIONS、ENABLE_PROD_MODE)完全可以继续留在原来的environment.ts里,不用全部迁移 - 这个方案不存在安全问题:后端API地址和Application Insights的前端检测密钥本来就是公开给浏览器端的参数,不存在泄露风险
内容的提问来源于stack exchange,提问作者Laura Seidel
相关产品推荐
相关产品推荐

