0

我遇到了 Angular 环境变量和 Azure Slots 的问题

我们希望使用提供静态 Angular 文件的应用服务,并且我们还希望使用 Azure 插槽来使我们的部署更安全。

我们要使用插槽的原因是:

  1. 确保代码在生产环境中正常运行,然后才能对所有人完全可用
  2. 将停机时间减少到几乎为零,因为在“上线”阶段没有部署任何构建

我们的 Angular 站点仅提供静态文件意味着插槽部署需要不同的构建来为每个插槽以不同的方式填充 env.json 环境设置。

我们正在考虑采取的解决方案是在同一个 Angular 网站中创建一个端点,并从 Angular 网站调用回其源以获取其配置。这种方式可以在 Azure 的暂存槽和生产槽中设置不同的配置,并且只需要一个 Angular 构建。

我们需要一些服务器端代码来获取这些 Azure 应用程序设置并将它们提供回站点上的端点。我们还没有决定我们用来创建那个端点的技术——我们目前正在考虑 .Net Core 或 NodeJs,因为它们似乎很适合 Angular 产品和开发团队。

有没有人有任何插入服务器端组件来为以前的静态 Angular 网站提供配置的经验?

4

3 回答 3

3

为了满足您的要求,您只需将以下 PHP 文件放入您的站点根文件夹即可。http://<websitename>.azurewebsites.net/appSettings.php然后通过您的 Angular 应用程序向端点发送 GET 请求。这将为您提供一个包含所有App 设置的 JSON 对象。

appSettings.php

<?php

$appSettings = [];

foreach ($_SERVER as $key => $value) {

    if(preg_match('/^APPSETTING_/', $key)) {
        $appSettings[str_replace('APPSETTING_', '', $key)] = $value;
    }
}

header('Content-Type: application/json');
echo json_encode($appSettings);
于 2017-03-10T06:58:08.850 回答
1

也许有人仍然需要它。我建议更接近所选技术并公开类似于以前的 php 答案的 node.js api。

我创建在 Azure AppService 中公开的端点http://<websitename>.azurewebsites.net/app-settings,如下所示:

将 index.js 文件添加到 Angular 代码中的 src 目录中:

var http = require('http');
var server = http.createServer(function (request, response) {
    response.writeHead(200, { "Content-Type": "application/json" });
    var result = {};
    result.someAppSetting = process.env.SomeApplicationSetting;
    var jsonResult = JSON.stringify(result);
    response.end(jsonResult);
});
var port = process.env.PORT || 1337;
server.listen(port);
console.log("Server exposing api for reading application settings running at http://localhost:%d", port);

因此,响应包含 json 以及SomeApplicationSetting从 env vars 中检索到的应用程序设置process.env.SomeApplicationSetting。当然,您可以采用其他公开变量的策略,例如仅将一些前缀设置添加到 json 或任何其他设置。

将 index.js 添加到 angular.json 中的资产:

"assets": [
  "src/favicon.ico",
  "src/assets",
  "src/web.config",
  "src/index.js"
],

然后在 web.config 中添加以下重写规则:

<rule name="Read app settings" stopProcessing="true">
  <match url="app-settings" />
  <action type="Rewrite" url="index.js"/>
</rule>
于 2019-01-29T14:04:09.403 回答
0

我查看了所有解决方案,并创建了一个在 Azure 和本地计算机(本地主机)上运行的解决方案。这取决于构建 - prod(从天蓝色读取)或dev(从本地资产文件夹读取)天蓝色插槽。

也许它对某人有帮助。

首先,您需要像Aaron Chen提到的那样添加这个小 php 文件。在src文件夹下的 Angular 结构中:

src/appSettings.php

$appSettings = [];

foreach ($_SERVER as $key => $value) {

    if(preg_match('/^APPSETTING_/', $key)) {
        $appSettings[str_replace('APPSETTING_', '', $key)] = $value;
    }
}

header('Content-Type: application/json');
echo json_encode($appSettings, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

需要修改angular.json文件。您需要添加assets"src/appSettings.php"

        "assets": [
          "src/favicon.ico",
          "src/assets",
          "src/appSettings.php"
        ],

此解决方案从链接中的 azure 获取所有配置http://<websitename>.azurewebsites.net/appSettings.php。这仅在 Azure 中有效(需要身份验证)。对于本地开发,您需要创建一个 Json 文件,其中包含该src/assets文件夹下的所有 Azure 插槽。

`assets/config/backend.json`;

要加载 Json 需要创建的配置

src/app/app.config.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpBackend  } from '@angular/common/http';
import { AppSettings } from './models/AppSettings.model';
import { environment } from 'src/environments/environment';

@Injectable()
export class AppConfig {
    static appSettings: AppSettings;

    private http: HttpClient;
    constructor( handler: HttpBackend) {
        this.http = new HttpClient(handler);
    }

    public load() {
        let backendConfigUrl: string;
        if (environment.production) {
            backendConfigUrl = window.location.origin + '/appsettings.php';
        } else {
            backendConfigUrl = `assets/config/backend.json`;
        }
        console.log(backendConfigUrl);

        return new Promise<void>((resolve, reject) => {
            this.http.get<AppSettings>(backendConfigUrl).toPromise().then((response: AppSettings) => {
                AppConfig.appSettings = response;
                resolve();
            }).catch((response: any) => {
               reject(`Could not load file ${backendConfigUrl}: ${JSON.stringify(response)}`);
            });
        });
    }
}

然后修改src/app/app.module.ts以在应用程序启动之前加载配置。

export function initializeApp(appConfig: AppConfig) {
  return () => appConfig.load().then(() => {
    console.log(AppConfig.appSettings)
  });
}

 providers: [
    AppConfig,
    {
      provide: APP_INITIALIZER,
      useFactory: initializeApp,
      deps: [AppConfig],
      multi: true
    },
  ]

从本地文件夹ng build加载配置。assetsng build --prodAzure 读取配置。ng serve和_ng serve --prod

于 2020-04-24T15:17:50.607 回答