如何基于Assets文件夹JS文件配置JwtModule.forRoot并导入至AppModule
Angular: 从Assets中的JS文件动态配置JwtModule的whitelistedDomains
我来帮你解决这个从Assets文件夹的JS文件获取配置来设置JwtModule的问题,这里有几个可行的方案,你可以根据自己的场景选择:
方案一:转为JSON文件(最简单直接的方式)
如果你的配置内容是静态的,最省心的方式就是把JS文件改成JSON格式,因为Angular对JSON文件的导入支持很友好:
- 把Assets里的配置文件(比如
config.js)重命名为config.json,内容调整为标准JSON格式:
{ "whitelistedDomains": ["http://172.20.130.27:8080"], "blacklistedRoutes": ["http://172.20.130.27:8080/api/auth"] }
- 在
tsconfig.json中确保开启了JSON模块支持(Angular 13+默认可能已经开启,旧版本需要手动加):
{ "compilerOptions": { "resolveJsonModule": true, "esModuleInterop": true } }
- 在AppModule中直接导入并使用:
import { NgModule } from '@angular/core'; // 其他必要导入... import apiConfig from '../assets/config.json'; @NgModule({ imports: [ BrowserModule, HttpClientModule, FormsModule, ReactiveFormsModule, BrowserAnimationsModule, AccordionModule.forRoot(), ModalModule.forRoot(), RouterModule.forRoot(appRoutes), ButtonsModule.forRoot(), PaginationModule.forRoot(), BsDropdownModule.forRoot(), BsDatepickerModule.forRoot(), AppRoutingModule, FileUploadModule, JwtModule.forRoot({ config: { tokenGetter: tokenGetter, whitelistedDomains: apiConfig.whitelistedDomains, blacklistedRoutes: apiConfig.blacklistedRoutes } }) ], // 其他配置... }) export class AppModule { }
方案二:保留JS文件,通过TypeScript声明导入
如果你必须保留JS文件的格式,可以通过TypeScript的声明文件来解决导入问题:
- 确保你的JS文件使用ES模块导出配置,比如
assets/config.js:
export const apiConfig = { whitelistedDomains: ["http://172.20.130.27:8080"], blacklistedRoutes: ["http://172.20.130.27:8080/api/auth"] };
- 在你的AppModule所在目录创建一个声明文件
config.d.ts,用来告诉TypeScript这个JS模块的类型:
declare module '../assets/config.js' { export const apiConfig: { whitelistedDomains: string[], blacklistedRoutes: string[] }; }
- 现在就可以在AppModule中正常导入并使用了:
import { NgModule } from '@angular/core'; // 其他必要导入... import { apiConfig } from '../assets/config.js'; @NgModule({ imports: [ // 其他模块导入... JwtModule.forRoot({ config: { tokenGetter: tokenGetter, whitelistedDomains: apiConfig.whitelistedDomains, blacklistedRoutes: apiConfig.blacklistedRoutes } }) ], // 其他配置... }) export class AppModule { }
方案三:运行时通过HttpClient动态加载(适合配置动态变化的场景)
如果你的配置需要在运行时动态获取(比如后端可能更新配置),可以用HttpClient配合APP_INITIALIZER来提前加载配置:
- 创建一个配置服务
config.service.ts来加载和解析JS文件:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable, map } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class ConfigService { private apiConfig: { whitelistedDomains: string[], blacklistedRoutes: string[] } | null = null; constructor(private http: HttpClient) {} loadConfig(): Observable<void> { return this.http.get('/assets/config.js', { responseType: 'text' }).pipe( map(configText => { // 解析JS导出的对象,这里假设JS是export const apiConfig = {...}的格式 const module = {} as { apiConfig: typeof this.apiConfig }; eval(`(function() { ${configText} }).apply(module)`); this.apiConfig = module.apiConfig; }) ); } getConfig() { return this.apiConfig; } }
- 在AppModule中使用
APP_INITIALIZER确保配置在应用初始化前加载完成:
import { NgModule, APP_INITIALIZER } from '@angular/core'; import { ConfigService } from './config.service'; // 其他必要导入... // 初始化函数,确保配置加载完成 export function initConfig(configService: ConfigService) { return () => configService.loadConfig().toPromise(); } @NgModule({ imports: [ BrowserModule, HttpClientModule, // 其他模块导入... JwtModule.forRoot({ config: { tokenGetter: tokenGetter, whitelistedDomains: () => configService.getConfig()?.whitelistedDomains || [], blacklistedRoutes: () => configService.getConfig()?.blacklistedRoutes || [] } }) ], providers: [ ConfigService, { provide: APP_INITIALIZER, useFactory: initConfig, deps: [ConfigService], multi: true } ], // 其他配置... }) export class AppModule { }
注意:
eval的使用需要确保你的JS文件是可信的,避免注入风险。
内容的提问来源于stack exchange,提问作者Mohammad Khojastefard
相关产品推荐
相关产品推荐

