diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..471ef2b --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ +VITE_API_BASE_URL=http://127.0.0.1:9000/api +VITE_H5_API_BASE_URL=/api +API_PROXY_TARGET=http://127.0.0.1:9000 diff --git a/config/runtime.js b/config/runtime.js index c1edabb..e6c09d8 100644 --- a/config/runtime.js +++ b/config/runtime.js @@ -1,4 +1,10 @@ const configuredApiRoot = import.meta.env.VITE_API_BASE_URL || '' +let selectedApiRoot = configuredApiRoot || '/api' -export const API_ROOT = String(configuredApiRoot || '/api').replace(/\/$/, '') +// H5 必须请求同源地址,由 Vite 开发服务器代理到国内 Gateway,避免浏览器 CORS。 +// #ifdef H5 +selectedApiRoot = import.meta.env.VITE_H5_API_BASE_URL || '/api' +// #endif + +export const API_ROOT = String(selectedApiRoot).replace(/\/$/, '') export const PLATFORM_API_ROOT = `${API_ROOT}/platform/v1` diff --git a/tests/page-contract.test.mjs b/tests/page-contract.test.mjs index 0a8b258..f01869b 100644 --- a/tests/page-contract.test.mjs +++ b/tests/page-contract.test.mjs @@ -23,8 +23,8 @@ test('application uses the Vue 3 uni-app entry and no unused Android permissions }) test('login uses the real auth endpoint and relaunches to the modular workbench', async () => { - const [login, auth, session, runtime] = await Promise.all([ - read('../pages/login/login.vue'), read('../api/auth.js'), read('../stores/session.js'), read('../config/runtime.js') + const [login, auth, session, runtime, vite] = await Promise.all([ + read('../pages/login/login.vue'), read('../api/auth.js'), read('../stores/session.js'), read('../config/runtime.js'), read('../vite.config.js') ]) for (const text of ['柏悦物流 · PDA作业端', '工号 / 用户名', '登录中']) assert.match(login, new RegExp(text)) assert.doesNotMatch(login, /DEMO_ACCOUNTS|快捷登录|作业仓库/) @@ -39,7 +39,11 @@ test('login uses the real auth endpoint and relaunches to the modular workbench' assert.match(session, /pda-login-account-preference/) assert.match(session, /claims\.app_code !== 'PLATFORM'/) assert.match(runtime, /import\.meta\.env\.VITE_API_BASE_URL/) + assert.match(runtime, /#ifdef H5[\s\S]*?VITE_H5_API_BASE_URL \|\| '\/api'/) assert.doesNotMatch(runtime, /typeof\s+import\.meta/) + assert.match(vite, /API_PROXY_TARGET/) + assert.match(vite, /'\/api'[\s\S]*?target: proxyTarget[\s\S]*?changeOrigin: true/) + assert.match(vite, /removeHeader\('origin'\)/) assert.match(login, /uni\.reLaunch\(\{ url: '\/pages\/home\/home' \}\)/) }) diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..6f4b9d5 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,24 @@ +import { defineConfig, loadEnv } from 'vite' +import uni from '@dcloudio/vite-plugin-uni' + +export default defineConfig(({ mode }) => { + const env = loadEnv(mode, process.cwd(), '') + const proxyTarget = env.API_PROXY_TARGET || 'http://127.0.0.1:9000' + + return { + plugins: [uni()], + server: { + proxy: { + '/api': { + target: proxyTarget, + changeOrigin: true, + configure(proxy) { + proxy.on('proxyReq', (proxyRequest) => { + proxyRequest.removeHeader('origin') + }) + } + } + } + } + } +})