fix: 开发代理避免 CORS,ideship Track 路径去重段
All checks were successful
Build and Deploy Front / deploy (push) Successful in 5m40s
All checks were successful
Build and Deploy Front / deploy (push) Successful in 5m40s
本地开发改为同源代理到生产/测试 API;ideship 将 /Track/Track 归一为 /track/Track,避免 404。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
c0c37a4eac
commit
2a51677908
@ -1,18 +1,13 @@
|
||||
# =============================================================================
|
||||
# 本地开发默认 → 测试环境 oms.nanafa.com / api.nanafa.com
|
||||
# 切换到生产 API:pnpm dev:ideship (加载 .env.ideship)
|
||||
# 发版构建:pnpm build(生产) / pnpm build:test(测试)
|
||||
# 本地开发默认 → 测试环境(Vite 代理到 api.nanafa.com,无浏览器 CORS)
|
||||
# 切生产:pnpm dev:ideship
|
||||
# =============================================================================
|
||||
VITE_DEPLOY_TARGET=nanafa
|
||||
VITE_API_ORIGIN=http://api.nanafa.com
|
||||
VITE_API_ADMIN_URL=http://api.nanafa.com/admin
|
||||
VITE_OMS_ADMIN_URL=http://api.nanafa.com/admin
|
||||
VITE_API_ASSET_ORIGIN=http://api.nanafa.com/admin
|
||||
VITE_API_ORIGIN=http://api.nanafa.com
|
||||
|
||||
# 企业微信客服
|
||||
VITE_WECOM_KF_URL=https://work.weixin.qq.com/kfid/kfcae09c206f6c7045a
|
||||
|
||||
# 智谱 AI(接口映射脚本生成)
|
||||
VITE_ZHIPU_API_KEY=85bbbef6bafd4ca383eef04189decd07.lKVQHcLGtYE8oUn5
|
||||
VITE_ZHIPU_BASE_URL=/zhipu-api
|
||||
VITE_ZHIPU_MODEL=glm-5.1
|
||||
|
||||
@ -1,11 +1,9 @@
|
||||
# =============================================================================
|
||||
# 本地开发直连生产 API(ideship.com)— pnpm dev:ideship
|
||||
# 仅用于联调生产;正式发版请用 pnpm build(.env.production)
|
||||
# 本地开发直连生产 API(ideship)— pnpm dev:ideship
|
||||
# 浏览器仍请求 localhost,由 Vite 代理到 api.ideship.com(避免 CORS)
|
||||
# =============================================================================
|
||||
VITE_DEPLOY_TARGET=ideship
|
||||
VITE_API_ORIGIN=https://api.ideship.com
|
||||
VITE_API_ADMIN_URL=https://api.ideship.com/admin
|
||||
VITE_OMS_ADMIN_URL=https://api.ideship.com/admin
|
||||
VITE_API_ASSET_ORIGIN=https://api.ideship.com/admin
|
||||
VITE_API_ORIGIN=https://api.ideship.com
|
||||
|
||||
VITE_WECOM_KF_URL=https://work.weixin.qq.com/kfid/kfcae09c206f6c7045a
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
# =============================================================================
|
||||
# 测试环境(oms.nanafa.com)— pnpm build:test → vite build --mode nanafa
|
||||
# 三套 API:http://api.nanafa.com/{admin|itfx|track}
|
||||
# 前端站点:https://oms.nanafa.com
|
||||
# 测试环境构建(oms.nanafa.com)— pnpm build:test
|
||||
# =============================================================================
|
||||
VITE_DEPLOY_TARGET=nanafa
|
||||
VITE_API_ORIGIN=http://api.nanafa.com
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Admin API 地址(方案 A)
|
||||
* - 优先 VITE_API_ADMIN_URL(.env.production / .env.nanafa / .env.ideship 切换)
|
||||
* - 未配置且开发:相对路径走 Vite 代理
|
||||
* - 未配置且生产构建:默认 https://api.ideship.com/admin
|
||||
* - 开发:始终相对路径,由 Vite 代理到 VITE_OMS_ADMIN_URL(避免 localhost→api 跨域)
|
||||
* - 生产构建:VITE_API_ADMIN_URL / 默认 https://api.ideship.com/admin
|
||||
*/
|
||||
|
||||
function normalizeBase(base: string): string {
|
||||
@ -22,34 +21,27 @@ function configuredAdminBase(): string | undefined {
|
||||
return undefined
|
||||
}
|
||||
|
||||
function prodAdminBase(): string {
|
||||
return configuredAdminBase() ?? DEFAULT_PROD_ADMIN
|
||||
}
|
||||
|
||||
/** 浏览器请求 Admin API(OpenAPI.BASE 或 omsUrl/orderUrl 等) */
|
||||
export function resolveAdminApiPath(path: string): string {
|
||||
const p = ensureLeadingSlash(path)
|
||||
const configured = configuredAdminBase()
|
||||
if (configured) {
|
||||
return `${configured}${p}`
|
||||
}
|
||||
if (!import.meta.env.DEV) {
|
||||
return `${DEFAULT_PROD_ADMIN}${p}`
|
||||
}
|
||||
// 开发走同源代理,不直连远程(生产 CORS 不放行 localhost)
|
||||
if (import.meta.env.DEV) {
|
||||
return p
|
||||
}
|
||||
return `${configuredAdminBase() ?? DEFAULT_PROD_ADMIN}${p}`
|
||||
}
|
||||
|
||||
export function resolveOpenApiBase(): string {
|
||||
const configured = configuredAdminBase()
|
||||
if (configured) return configured
|
||||
if (!import.meta.env.DEV) {
|
||||
return DEFAULT_PROD_ADMIN
|
||||
}
|
||||
if (import.meta.env.DEV) {
|
||||
return ''
|
||||
}
|
||||
return configuredAdminBase() ?? DEFAULT_PROD_ADMIN
|
||||
}
|
||||
|
||||
/** 桌面 Agent 等直连 Admin 网关 */
|
||||
/** 桌面 Agent 等直连 Admin 网关(不受浏览器 CORS 限制) */
|
||||
export function resolveDirectAdminApiUrl(): string {
|
||||
const fromOms = import.meta.env.VITE_OMS_ADMIN_URL as string | undefined
|
||||
if (fromOms?.trim()) return normalizeBase(fromOms)
|
||||
const configured = configuredAdminBase()
|
||||
if (configured) return configured
|
||||
if (import.meta.env.DEV) {
|
||||
@ -60,14 +52,12 @@ export function resolveDirectAdminApiUrl(): string {
|
||||
|
||||
/** 静态资源(uploads)在 Admin wwwroot,须带 `/admin`。 */
|
||||
export function resolveAdminAssetOrigin(): string {
|
||||
if (import.meta.env.DEV) {
|
||||
return ''
|
||||
}
|
||||
const override = import.meta.env.VITE_API_ASSET_ORIGIN as string | undefined
|
||||
if (override?.trim()) {
|
||||
return normalizeBase(override)
|
||||
}
|
||||
const configured = configuredAdminBase()
|
||||
if (configured) return configured
|
||||
if (!import.meta.env.DEV) {
|
||||
return DEFAULT_PROD_ADMIN
|
||||
}
|
||||
return ''
|
||||
return configuredAdminBase() ?? DEFAULT_PROD_ADMIN
|
||||
}
|
||||
|
||||
@ -20,9 +20,10 @@ const SPA_API_PREFIXES = [
|
||||
const DEFAULT_PROD_API = 'https://api.ideship.com'
|
||||
|
||||
function prodApiOrigin(): string | null {
|
||||
// 开发走 Vite 代理,不改写为跨域绝对地址
|
||||
if (import.meta.env.DEV) return null
|
||||
const override = (import.meta.env.VITE_API_ORIGIN as string | undefined)?.trim()
|
||||
if (override) return override.replace(/\/$/, '')
|
||||
if (import.meta.env.DEV) return null
|
||||
return DEFAULT_PROD_API
|
||||
}
|
||||
|
||||
@ -76,11 +77,28 @@ export function rewriteBrowserApiPath(url: string): string {
|
||||
}
|
||||
|
||||
if (path.startsWith('/Track')) {
|
||||
// ideship:/Track/Track/Order → /track/Track/Order
|
||||
// nanafa:保持 /track + /Track/Track/Order
|
||||
const useSingle =
|
||||
String(import.meta.env.VITE_DEPLOY_TARGET || '').toLowerCase() === 'ideship' ||
|
||||
/ideship\.com/i.test(origin)
|
||||
if (useSingle && path.startsWith('/Track/Track/')) {
|
||||
return `${origin}/track/Track/${path.slice('/Track/Track/'.length)}`
|
||||
}
|
||||
return `${origin}/track${path}`
|
||||
}
|
||||
|
||||
if (path.startsWith('/trackApi/')) {
|
||||
return `${origin}/track/${path.slice('/trackApi/'.length)}`
|
||||
const rest = path.slice('/trackApi/'.length)
|
||||
const useSingle =
|
||||
String(import.meta.env.VITE_DEPLOY_TARGET || '').toLowerCase() === 'ideship' ||
|
||||
/ideship\.com/i.test(origin)
|
||||
// trackApi/Track/Order → /track/Track/Order
|
||||
if (useSingle && rest.startsWith('Track/')) {
|
||||
return `${origin}/track/${rest}`
|
||||
}
|
||||
// nanafa 历史:trackApi/Track/Order → /track/Track/Track/Order(与双 Track 客户端一致时由调用方决定)
|
||||
return `${origin}/track/${rest}`
|
||||
}
|
||||
|
||||
return path
|
||||
|
||||
@ -14,10 +14,33 @@ import configCompressPlugin from './config/plugin/compress';
|
||||
|
||||
export default defineConfig(({ mode }) => {
|
||||
const env = loadEnv(mode, process.cwd(), '');
|
||||
// Admin API 目标:由 VITE_OMS_ADMIN_URL 决定(开发默认线上)
|
||||
// Admin API 目标:由 VITE_OMS_ADMIN_URL 决定(开发走代理,避免浏览器 CORS)
|
||||
const omsAdminTarget = (
|
||||
env.VITE_OMS_ADMIN_URL || 'http://api.nanafa.com/admin'
|
||||
env.VITE_OMS_ADMIN_URL || env.VITE_API_ADMIN_URL || 'http://api.nanafa.com/admin'
|
||||
).replace(/\/$/, '');
|
||||
// API 根(itfx/track):优先 VITE_API_ORIGIN,否则从 Admin URL 去掉 /admin
|
||||
const apiOrigin = (
|
||||
env.VITE_API_ORIGIN ||
|
||||
omsAdminTarget.replace(/\/admin\/?$/, '') ||
|
||||
'http://api.nanafa.com'
|
||||
).replace(/\/$/, '');
|
||||
// ideship:PATHBASE=/track → /track/Track/Order/...
|
||||
// nanafa:网关仍吃 /track/Track/Track/Order/...(前端历史双 Track)
|
||||
const trackUseSingleSegment =
|
||||
String(env.VITE_DEPLOY_TARGET || '').toLowerCase() === 'ideship' ||
|
||||
/ideship\.com/i.test(apiOrigin);
|
||||
|
||||
const rewriteTrackProxyPath = (path: string) => {
|
||||
if (trackUseSingleSegment) {
|
||||
if (path.startsWith('/Track/Track/')) {
|
||||
return `/track/Track/${path.slice('/Track/Track/'.length)}`;
|
||||
}
|
||||
if (path.startsWith('/Track/') || path === '/Track') {
|
||||
return `/track${path}`;
|
||||
}
|
||||
}
|
||||
return `/track${path}`;
|
||||
};
|
||||
|
||||
return {
|
||||
server: {
|
||||
@ -34,16 +57,17 @@ export default defineConfig(({ mode }) => {
|
||||
changeOrigin: true,
|
||||
secure: false,
|
||||
},
|
||||
// 上传静态资源:/api/upload/xxx -> http://api.nanafa.com/upload/xxx
|
||||
// 上传静态资源:/api/upload/xxx -> {apiOrigin}/upload/xxx(Admin 多为 /admin/uploads)
|
||||
// 必须放在通用 /api 规则前,避免被转发到 /itfx/upload 导致 404
|
||||
'/api/upload': {
|
||||
target: 'http://api.nanafa.com',
|
||||
target: apiOrigin,
|
||||
changeOrigin: true,
|
||||
secure: false,
|
||||
rewrite: (path) => path.replace(/^\/api/, ''),
|
||||
timeout: 30000,
|
||||
proxyTimeout: 30000,
|
||||
},
|
||||
// Admin API:目标由 VITE_OMS_ADMIN_URL 决定(默认 http://api.nanafa.com/admin)
|
||||
// Admin API:目标由 VITE_OMS_ADMIN_URL 决定
|
||||
'/rbac': {
|
||||
target: omsAdminTarget,
|
||||
changeOrigin: true,
|
||||
@ -281,22 +305,24 @@ export default defineConfig(({ mode }) => {
|
||||
secure: false,
|
||||
rewrite: (path) => path.replace(/^\/api/, ''),
|
||||
},
|
||||
// 轨迹(track)43.139.210.35:8889 -> http://api.nanafa.com/track,路径与 rbac、api 一致:/Track/xxx
|
||||
// 轨迹(track):{apiOrigin}/track/...
|
||||
'/Track': {
|
||||
target: 'http://api.nanafa.com',
|
||||
target: apiOrigin,
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => '/track' + path,
|
||||
secure: false,
|
||||
rewrite: rewriteTrackProxyPath,
|
||||
configure: (proxy) => {
|
||||
proxy.on('error', (err, req, res) => {
|
||||
console.error('proxy error', err);
|
||||
});
|
||||
},
|
||||
},
|
||||
// API(itfx)43.139.210.35:8888 -> http://api.nanafa.com/itfx
|
||||
// API(itfx):{apiOrigin}/itfx
|
||||
// 使用正则表达式匹配,排除前端路由路径
|
||||
'^/api/(?!upstreamInterface|upstreamInterfaceConfig|upstreamInterfaceConfigEdit|downstreamInterface|downstreamInterface/newPort|appList|appList/createApplication|requestLog|callStatistics|apiDebugger|trackApi)': {
|
||||
target: 'http://api.nanafa.com/itfx',
|
||||
target: `${apiOrigin}/itfx`,
|
||||
changeOrigin: true,
|
||||
secure: false,
|
||||
rewrite: (path) => path.replace(/^\/api/, ''),
|
||||
timeout: 30000,
|
||||
proxyTimeout: 30000,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user