在运行时在Angular中读取服务器环境变量

时间:2020-10-29 09:25:41

标签: angular docker

我是新手。我已经在AWS的Docker容器中部署了一个角度应用程序。该应用程序需要连接到AWS S3存储桶。我不需要对aws键进行硬编码,因此可以在docker中设置环境变量。部署了angular使得ng构建中的dist文件夹由nginx docker容器提供服务。

一旦将dist文件夹中的内容提供给服务器,是否可以按角度读取服务器环境变量?像php和nodejs中的env函数

2 个答案:

答案 0 :(得分:2)

不幸的是,无法像nodejs或Spring Boot这样的服务器框架所提供的机制一样,在Angular中读取环境变量。

但是,您可以在Angular应用程序引导之前从服务器加载环境(请先阅读以下缺点,然后再采用此路径)。

从服务器加载环境变量:

  • 从根模块(例如AppModule)中删除引导程序组件,以使其不会自动引导
  • 在根目录中创建一个单例服务,以加载环境变量,例如:
import { Injectable } from "@angular/core";

@Injectable({ providedIn: "root" })
export class EnvService {
  public myEnv: string;

  fetchEnv() {
    // This has to retrieved from some server.
    return fetch("some-url").then(env => {this.myEnv = env.myEnv; return Promise.resolve("env loaded");};
  }
}
  • 在根模块中延迟引导程序,直到环境加载完毕为止:
@NgModule({
  imports: [BrowserModule, FormsModule],
  declarations: [AppComponent, HelloComponent]
})
export class AppModule {
  constructor(private envService: EnvService) {}
  ngDoBootstrap(app) {
    this.envService.fetchEnv().then(() => app.bootstrap(AppComponent));
  }
}

这种方法有两个缺点:

  • 在加载其他环境变量之前,必须先知道从中检索环境设置的网址
  • 如果无法加载环境变量,Angular应用将无法启动。使用Docker时,您可以在Docker容器内托管一个小型Web服务器,该服务器在Angular应用的专用端点上提供环境变量。但是,这可能会带来自己的问题,因为这会使创建Angular Docker容器更加复杂。

因此,我建议在构建过程中配置env变量。

有两种方法可以在构建过程中设置环境变量

1)使用自定义Webpack配置在构建中设置环境变量

请参阅此article

您可以在angular.json中指定自定义的webpack配置:

"architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "extra-webpack.config.js"
            },
...

webpack配置文件如下所示:

const webpack = require('webpack');

module.exports = {
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        // Here you can set your env variables.
        SERVER_URL: JSON.stringify(process.env.SERVER_URL)
      }
    })
  ]
}

此方法需要更多的依赖项:

@angular-builders/custom-webpack
dotenv

2)在构建过程中动态创建环境文件

例如参见自动生成的src / environments / environment.prod.ts。 您可以在构建过程中使用正确的环境值生成该文件,或在此文件中替换占位符。

编辑:另请参见法比奥的答案。无论如何,您可能都不希望用户知道S3存储桶,应尽可能通过Web服务器将请求路由到存储桶。

答案 1 :(得分:1)

php和nodejs在服务器端运行,这就是为什么它们可以访问服务器环境变量。

由于Angular在浏览器中运行,因此您的angular应用程序可以读取的所有内容都会向客户端公开。我假设您不希望您的AWS密钥在客户端上浮动,任何用户都可以准备它们。这会使您的后端受到恶意使用。

如果您确实选择走这条路,那么您始终可以在您的角度应用程序正在谈论的服务器应用程序中创建一个端点以公开服务器环境变量。

更常见的模式是让服务器端点将数据提供给有角度的数据而不是其环境变量:

  1. 您的角度服务从服务中召集一个点;
  2. 服务器使用其配置和变量获取数据;
  3. 服务器使用数据响应角度服务调用;

我过度简化了服务器交互,因为这是我建议您与该问题分开阅读的内容。 This post应该可以帮助您开始进行后端/前端分离。