Files
zyt/REGION_API_PRODUCTION_FIX.md
2026-04-17 09:47:17 +08:00

6.9 KiB

Region API Production URL Fix (省市区API生产环境URL修复)

Issue

The region data API was using a proxy path (/api-proxy/area/ChinaCitys.json) which only works in development mode. After building for production, the proxy is not available, causing the region selector to fail.

Root Cause

Vite's proxy configuration (vite.config.ts) only works during development (npm run dev). When the application is built for production (npm run build), the proxy is not included in the build output, and the relative path /api-proxy/... becomes invalid.

Solution

Use environment detection to switch between proxy URL (development) and full URL (production).

Changes Made

1. Updated prescription/index.vue

File: admin/src/views/consumer/prescription/index.vue

Changed from:

const response = await fetch('/api-proxy/area/ChinaCitys.json')

To:

// 开发环境使用代理,生产环境使用完整URL
const apiUrl = import.meta.env.DEV 
    ? '/api-proxy/area/ChinaCitys.json'
    : 'https://admin.zhenyangtang.com.cn/area/ChinaCitys.json'

const response = await fetch(apiUrl)

2. Updated prescription/order_list.vue

File: admin/src/views/consumer/prescription/order_list.vue

Applied the same change to the order list view.

How It Works

Environment Detection

Uses Vite's built-in environment variable import.meta.env.DEV:

  • Development (npm run dev): import.meta.env.DEV = true
  • Production (npm run build): import.meta.env.DEV = false

URL Selection Logic

const apiUrl = import.meta.env.DEV 
    ? '/api-proxy/area/ChinaCitys.json'           // Development: Use proxy
    : 'https://admin.zhenyangtang.com.cn/area/ChinaCitys.json'  // Production: Use full URL

Development Mode

  • Uses proxy path: /api-proxy/area/ChinaCitys.json
  • Vite proxy rewrites to: https://admin.zhenyangtang.com.cn/area/ChinaCitys.json
  • Avoids CORS issues during development

Production Mode

  • Uses full URL: https://admin.zhenyangtang.com.cn/area/ChinaCitys.json
  • Direct fetch from the actual server
  • No proxy needed

Benefits

1. Works in Both Environments

  • Development: Uses proxy for CORS-free development
  • Production: Uses direct URL for deployed application

2. No Build Configuration Changes

  • No need to modify build scripts
  • No environment-specific builds
  • Single codebase for all environments

3. Automatic Detection

  • Automatically switches based on environment
  • No manual configuration needed
  • No risk of using wrong URL

4. Maintains CORS Handling

  • Development: Proxy handles CORS
  • Production: Server should have proper CORS headers

Testing Steps

1. Test Development Mode

  1. Run development server:
    cd admin
    npm run dev
    
  2. Open browser console
  3. Check for log: 开始加载省市区数据...
  4. Verify it uses proxy URL
  5. Check region selector loads data

2. Test Production Build

  1. Build for production:
    cd admin
    npm run build
    
  2. Serve the built files:
    npm run preview
    # or deploy to production server
    
  3. Open browser console
  4. Check for log: 开始加载省市区数据...
  5. Verify it uses full URL
  6. Check region selector loads data

3. Verify URL in Network Tab

Development:

  • Request URL: http://localhost:5173/api-proxy/area/ChinaCitys.json
  • Proxied to: https://admin.zhenyangtang.com.cn/area/ChinaCitys.json

Production:

  • Request URL: https://admin.zhenyangtang.com.cn/area/ChinaCitys.json
  • Direct request (no proxy)

4. Test Fallback Data

If API fails in either environment, verify fallback data is used:

regionOptions.value = [
    {
        name: '四川省',
        children: [...]
    },
    ...
]

Alternative Solutions Considered

Option 1: Environment Variables (Not Chosen)

const apiUrl = import.meta.env.VITE_REGION_API_URL || '/api-proxy/area/ChinaCitys.json'

Pros: More flexible for different environments Cons: Requires environment-specific configuration files

Option 2: Relative Path (Not Chosen)

const apiUrl = '/area/ChinaCitys.json'

Pros: Simple Cons: Requires copying file to public folder, increases bundle size

Option 3: Backend API Endpoint (Not Chosen)

Create a backend endpoint to serve region data Pros: More control, can cache, can update without frontend deploy Cons: Requires backend changes, adds server load

Option 4: Current Solution (Chosen)

Use environment detection with conditional URL Pros:

  • Simple implementation
  • No additional configuration
  • Works in both environments
  • No backend changes needed Cons:
  • Hardcoded production URL (acceptable for this use case)

Production Server Requirements

CORS Headers

The production server hosting ChinaCitys.json should have proper CORS headers:

Access-Control-Allow-Origin: *
# or specific domain:
Access-Control-Allow-Origin: https://your-admin-domain.com

File Availability

Ensure the file is accessible at:

https://admin.zhenyangtang.com.cn/area/ChinaCitys.json

Alternative: Use Backend Proxy

If CORS is an issue in production, consider creating a backend endpoint:

// server/app/adminapi/controller/RegionController.php
public function getChinaCitys()
{
    $url = 'https://admin.zhenyangtang.com.cn/area/ChinaCitys.json';
    $data = file_get_contents($url);
    return json(['data' => json_decode($data, true)]);
}

Then update frontend to use:

const apiUrl = import.meta.env.DEV 
    ? '/api-proxy/area/ChinaCitys.json'
    : '/adminapi/region/getChinaCitys'  // Backend endpoint

Frontend:

  • admin/src/views/consumer/prescription/index.vue
    • Updated loadRegionData() function
  • admin/src/views/consumer/prescription/order_list.vue
    • Updated loadRegionData() function

Configuration:

  • admin/vite.config.ts
    • Proxy configuration (development only)

Documentation:

  • REGION_DATA_SETUP.md (should be updated to mention production URL)

Environment Variables Reference

Vite Built-in Variables:

  • import.meta.env.DEV - Boolean, true in development
  • import.meta.env.PROD - Boolean, true in production
  • import.meta.env.MODE - String, 'development' or 'production'

Usage Example:

if (import.meta.env.DEV) {
    console.log('Running in development mode')
}

if (import.meta.env.PROD) {
    console.log('Running in production mode')
}

console.log('Current mode:', import.meta.env.MODE)

Summary

Fixed production build issue with region API
Uses proxy in development for CORS-free development
Uses direct URL in production for deployed application
Automatic environment detection
No build configuration changes needed
Maintains fallback data for both environments
Applied to both prescription index and order list views

The region selector now works correctly in both development and production environments!