fix: 生产环境 API 同源,HF Space / Docker 前端可正常请求后端
Browse files
Dockerfile
CHANGED
|
@@ -11,11 +11,7 @@ RUN npm install
|
|
| 11 |
ENV NODE_ENV=production
|
| 12 |
ENV PATH=/app/node_modules/.bin:$PATH
|
| 13 |
|
| 14 |
-
#
|
| 15 |
-
RUN sed -i 's#\${baseUrl}##g' /app/src/views/AccountManagement.vue
|
| 16 |
-
RUN sed -i "s#\${import\.meta\.env\.VITE_API_BASE_URL || 'http:\/\/localhost:5409'}##g" /app/src/api/material.js
|
| 17 |
-
RUN sed -i 's#localhost:5409##g' /app/.env.production
|
| 18 |
-
|
| 19 |
RUN npm run build
|
| 20 |
|
| 21 |
|
|
|
|
| 11 |
ENV NODE_ENV=production
|
| 12 |
ENV PATH=/app/node_modules/.bin:$PATH
|
| 13 |
|
| 14 |
+
# 生产构建:.env.production 中 VITE_API_BASE_URL 为空,前端与 Flask 同源(见 sau_frontend/src/utils/apiBase.js)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
RUN npm run build
|
| 16 |
|
| 17 |
|
sau_frontend/.env.production
CHANGED
|
@@ -1,8 +1,8 @@
|
|
| 1 |
# 生产环境配置
|
| 2 |
NODE_ENV=production
|
| 3 |
|
| 4 |
-
# API
|
| 5 |
-
VITE_API_BASE_URL=
|
| 6 |
|
| 7 |
# 是否开启 mock
|
| 8 |
VITE_USE_MOCK=false
|
|
|
|
| 1 |
# 生产环境配置
|
| 2 |
NODE_ENV=production
|
| 3 |
|
| 4 |
+
# API:留空则与页面同源(Docker / HF Space 同一进程提供前后端)。本地直连后端可设为 http://127.0.0.1:5409
|
| 5 |
+
VITE_API_BASE_URL=
|
| 6 |
|
| 7 |
# 是否开启 mock
|
| 8 |
VITE_USE_MOCK=false
|
sau_frontend/src/api/material.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
import { http } from '@/utils/request'
|
|
|
|
| 2 |
|
| 3 |
// 素材管理API
|
| 4 |
export const materialApi = {
|
|
@@ -20,11 +21,13 @@ export const materialApi = {
|
|
| 20 |
|
| 21 |
// 下载素材
|
| 22 |
downloadMaterial: (filePath) => {
|
| 23 |
-
|
|
|
|
| 24 |
},
|
| 25 |
|
| 26 |
// 获取素材预览URL
|
| 27 |
getMaterialPreviewUrl: (filename) => {
|
| 28 |
-
|
|
|
|
| 29 |
}
|
| 30 |
}
|
|
|
|
| 1 |
import { http } from '@/utils/request'
|
| 2 |
+
import { getApiBase } from '@/utils/apiBase'
|
| 3 |
|
| 4 |
// 素材管理API
|
| 5 |
export const materialApi = {
|
|
|
|
| 21 |
|
| 22 |
// 下载素材
|
| 23 |
downloadMaterial: (filePath) => {
|
| 24 |
+
const b = getApiBase()
|
| 25 |
+
return `${b}/download/${filePath}`
|
| 26 |
},
|
| 27 |
|
| 28 |
// 获取素材预览URL
|
| 29 |
getMaterialPreviewUrl: (filename) => {
|
| 30 |
+
const b = getApiBase()
|
| 31 |
+
return `${b}/getFile?filename=${filename}`
|
| 32 |
}
|
| 33 |
}
|
sau_frontend/src/utils/apiBase.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* 生产环境前后端同源(Docker / Hugging Face Space)时请在 .env.production 中设 VITE_API_BASE_URL 为空。
|
| 3 |
+
* 开发环境使用 .env.development 中的 /api(Vite 代理到后端)。
|
| 4 |
+
*/
|
| 5 |
+
export function getApiBase() {
|
| 6 |
+
const v = import.meta.env.VITE_API_BASE_URL
|
| 7 |
+
if (v != null && String(v).trim() !== '') {
|
| 8 |
+
return String(v).replace(/\/$/, '')
|
| 9 |
+
}
|
| 10 |
+
return ''
|
| 11 |
+
}
|
sau_frontend/src/utils/request.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
| 1 |
import axios from 'axios'
|
| 2 |
import { ElMessage } from 'element-plus'
|
|
|
|
| 3 |
|
| 4 |
// 创建axios实例
|
| 5 |
const request = axios.create({
|
| 6 |
-
baseURL:
|
| 7 |
headers: {
|
| 8 |
'Content-Type': 'application/json'
|
| 9 |
}
|
|
|
|
| 1 |
import axios from 'axios'
|
| 2 |
import { ElMessage } from 'element-plus'
|
| 3 |
+
import { getApiBase } from '@/utils/apiBase'
|
| 4 |
|
| 5 |
// 创建axios实例
|
| 6 |
const request = axios.create({
|
| 7 |
+
baseURL: getApiBase(),
|
| 8 |
headers: {
|
| 9 |
'Content-Type': 'application/json'
|
| 10 |
}
|
sau_frontend/src/views/AccountManagement.vue
CHANGED
|
@@ -434,6 +434,7 @@ import { accountApi } from '@/api/account'
|
|
| 434 |
import { useAccountStore } from '@/stores/account'
|
| 435 |
import { useAppStore } from '@/stores/app'
|
| 436 |
import { http } from '@/utils/request'
|
|
|
|
| 437 |
|
| 438 |
// 获取账号状态管理
|
| 439 |
const accountStore = useAccountStore()
|
|
@@ -672,7 +673,7 @@ const handleDelete = (row) => {
|
|
| 672 |
// 下载Cookie文件
|
| 673 |
const handleDownloadCookie = (row) => {
|
| 674 |
// 从后端获取Cookie文件
|
| 675 |
-
const baseUrl =
|
| 676 |
const downloadUrl = `${baseUrl}/downloadCookie?filePath=${encodeURIComponent(row.filePath)}`
|
| 677 |
|
| 678 |
// 创建一个隐藏的链接来触发下载
|
|
@@ -792,7 +793,7 @@ const connectSSE = (platform, name) => {
|
|
| 792 |
const type = platformTypeMap[platform] || '1'
|
| 793 |
|
| 794 |
// 创建SSE连接
|
| 795 |
-
const baseUrl =
|
| 796 |
const url = `${baseUrl}/login?type=${type}&id=${encodeURIComponent(name)}`
|
| 797 |
|
| 798 |
eventSource = new EventSource(url)
|
|
|
|
| 434 |
import { useAccountStore } from '@/stores/account'
|
| 435 |
import { useAppStore } from '@/stores/app'
|
| 436 |
import { http } from '@/utils/request'
|
| 437 |
+
import { getApiBase } from '@/utils/apiBase'
|
| 438 |
|
| 439 |
// 获取账号状态管理
|
| 440 |
const accountStore = useAccountStore()
|
|
|
|
| 673 |
// 下载Cookie文件
|
| 674 |
const handleDownloadCookie = (row) => {
|
| 675 |
// 从后端获取Cookie文件
|
| 676 |
+
const baseUrl = getApiBase()
|
| 677 |
const downloadUrl = `${baseUrl}/downloadCookie?filePath=${encodeURIComponent(row.filePath)}`
|
| 678 |
|
| 679 |
// 创建一个隐藏的链接来触发下载
|
|
|
|
| 793 |
const type = platformTypeMap[platform] || '1'
|
| 794 |
|
| 795 |
// 创建SSE连接
|
| 796 |
+
const baseUrl = getApiBase()
|
| 797 |
const url = `${baseUrl}/login?type=${type}&id=${encodeURIComponent(name)}`
|
| 798 |
|
| 799 |
eventSource = new EventSource(url)
|
sau_frontend/src/views/PublishCenter.vue
CHANGED
|
@@ -498,9 +498,10 @@ import { useAccountStore } from '@/stores/account'
|
|
| 498 |
import { useAppStore } from '@/stores/app'
|
| 499 |
import { materialApi } from '@/api/material'
|
| 500 |
import { http } from '@/utils/request'
|
|
|
|
| 501 |
|
| 502 |
-
// API base URL
|
| 503 |
-
const apiBaseUrl =
|
| 504 |
|
| 505 |
// Authorization headers
|
| 506 |
const authHeaders = computed(() => ({
|
|
|
|
| 498 |
import { useAppStore } from '@/stores/app'
|
| 499 |
import { materialApi } from '@/api/material'
|
| 500 |
import { http } from '@/utils/request'
|
| 501 |
+
import { getApiBase } from '@/utils/apiBase'
|
| 502 |
|
| 503 |
+
// API base URL(生产同源时为空,请求走当前域名)
|
| 504 |
+
const apiBaseUrl = getApiBase()
|
| 505 |
|
| 506 |
// Authorization headers
|
| 507 |
const authHeaders = computed(() => ({
|