如何在Angular/React中访问原生JS变量实现免重建切换API环境
实现客户端可切换多环境API的方案
第一步:修正你的constants.js文件
原文件存在重复键(两个dev)和拼写错误,先修正为正确结构,同时把配置挂载到window对象,方便客户端直接访问且无需打包进应用:
// constants.js window.apiConfigs = { "dev": { "url": "http://www.development.com/api/v1/xxx" }, "stg": { "url": "http://www.staging.com/api/v1/xxx" }, "qa": { "url": "http://www.qualityassurance.com/api/v1/xxx" }, "prod": { "url": "http://www.production.com/api/v1/xxx" } }
React 实现方案
1. 静态部署constants.js
把修正后的文件放到项目public目录下,React构建时会直接复制该文件到产物根目录,不会被webpack编译。
2. 封装API工具类
在应用中读取配置并封装请求、切换方法:
// src/utils/api.js // 读取本地存储的选中环境,默认用dev let currentEnv = localStorage.getItem('selectedApiEnv') || 'dev'; let currentApiUrl = window.apiConfigs[currentEnv]?.url; // 通用请求方法 export const fetchData = async (endpoint) => { const response = await fetch(`${currentApiUrl}/${endpoint}`); return response.json(); }; // 切换环境方法 export const switchApiEnv = (env) => { if (window.apiConfigs[env]) { currentEnv = env; currentApiUrl = window.apiConfigs[env].url; localStorage.setItem('selectedApiEnv', env); // 刷新页面确保配置生效 window.location.reload(); } else { console.error('无效的环境配置'); } };
3. 添加环境切换UI
在设置页面添加下拉选择器:
// src/components/EnvSwitcher.js import { switchApiEnv } from '../utils/api'; const EnvSwitcher = () => { const currentEnv = localStorage.getItem('selectedApiEnv') || 'dev'; const envs = Object.keys(window.apiConfigs); return ( <div> <label>选择API环境:</label> <select value={currentEnv} onChange={(e) => switchApiEnv(e.target.value)} > {envs.map(env => ( <option key={env} value={env}> {env.toUpperCase()} </option> ))} </select> </div> ); }; export default EnvSwitcher;
Angular 实现方案
1. 静态部署并引入constants.js
把文件放到src/assets目录,在index.html中引入:
<!-- src/index.html --> <body> <app-root></app-root> <script src="assets/constants.js"></script> </body>
2. 封装API配置服务
创建全局服务管理环境配置:
// src/app/services/api-config.service.ts import { Injectable } from '@angular/core'; declare global { interface Window { apiConfigs: Record<string, {url: string}>; } } @Injectable({ providedIn: 'root' }) export class ApiConfigService { currentEnv: string; currentApiUrl: string; constructor() { this.currentEnv = localStorage.getItem('selectedApiEnv') || 'dev'; this.currentApiUrl = window.apiConfigs[this.currentEnv]?.url; } switchEnv(env: string) { if (window.apiConfigs[env]) { this.currentEnv = env; this.currentApiUrl = window.apiConfigs[env].url; localStorage.setItem('selectedApiEnv', env); window.location.reload(); } else { console.error('无效的环境配置'); } } getApiUrl(endpoint: string): string { return `${this.currentApiUrl}/${endpoint}`; } }
3. 配置HTTP拦截器自动添加前缀
创建拦截器统一处理API地址:
// src/app/interceptors/api-url.interceptor.ts import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; import { Observable } from 'rxjs'; import { ApiConfigService } from '../services/api-config.service'; @Injectable() export class ApiUrlInterceptor implements HttpInterceptor { constructor(private apiConfigService: ApiConfigService) {} intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { // 仅对非外部请求添加API前缀 if (!request.url.startsWith('http')) { const apiUrl = this.apiConfigService.getApiUrl(request.url); request = request.clone({ url: apiUrl }); } return next.handle(request); } }
在app.module.ts注册拦截器:
import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { ApiUrlInterceptor } from './interceptors/api-url.interceptor'; @NgModule({ providers: [ { provide: HTTP_INTERCEPTORS, useClass: ApiUrlInterceptor, multi: true } ] }) export class AppModule { }
4. 添加环境切换组件
创建选择组件:
// src/app/components/env-switcher/env-switcher.component.ts import { Component } from '@angular/core'; import { ApiConfigService } from '../../services/api-config.service'; @Component({ selector: 'app-env-switcher', template: ` <div> <label>选择API环境:</label> <select [(ngModel)]="currentEnv" (change)="switchEnv($event.target.value)"> <option *ngFor="let env of envList" [value]="env">{{env.toUpperCase()}}</option> </select> </div> ` }) export class EnvSwitcherComponent { currentEnv: string; envList: string[]; constructor(private apiConfigService: ApiConfigService) { this.currentEnv = this.apiConfigService.currentEnv; this.envList = Object.keys(window.apiConfigs); } switchEnv(env: string) { this.apiConfigService.switchEnv(env); } }
关键说明
constants.js独立于应用代码,后续修改配置只需替换该文件,无需重建项目。- 用
localStorage保存用户选择的环境,刷新页面不会丢失配置。 - 切换后刷新页面是为了确保所有API请求使用新配置,也可根据需求优化为不刷新(需重新初始化所有API相关实例)。
内容的提问来源于stack exchange,提问作者dinu0101
相关产品推荐
相关产品推荐

