You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 17:13:10