diff --git a/src/core/api-client.js b/src/core/api-client.js index 20e82bc..33ec9a3 100644 --- a/src/core/api-client.js +++ b/src/core/api-client.js @@ -8,6 +8,21 @@ export class ApiClient { this.setApiBase(apiBase); } + buildHeaders(options = {}) { + const customHeaders = options.headers || {}; + const headers = { + 'Authorization': `Bearer ${this.managementKey}`, + ...customHeaders + }; + const hasContentType = Object.keys(headers).some(key => key.toLowerCase() === 'content-type'); + const body = options.body; + const isFormData = typeof FormData !== 'undefined' && body instanceof FormData; + if (!hasContentType && !isFormData) { + headers['Content-Type'] = 'application/json'; + } + return headers; + } + normalizeBase(input) { let base = (input || '').trim(); if (!base) return ''; @@ -37,11 +52,7 @@ export class ApiClient { async request(endpoint, options = {}) { const url = `${this.apiUrl}${endpoint}`; - const headers = { - 'Authorization': `Bearer ${this.managementKey}`, - 'Content-Type': 'application/json', - ...options.headers - }; + const headers = this.buildHeaders(options); const response = await fetch(url, { ...options, @@ -59,4 +70,18 @@ export class ApiClient { return await response.json(); } + + // 返回原始 Response,供下载/自定义解析使用 + async requestRaw(endpoint, options = {}) { + const url = `${this.apiUrl}${endpoint}`; + const headers = this.buildHeaders(options); + const response = await fetch(url, { + ...options, + headers + }); + if (typeof this.onVersionUpdate === 'function') { + this.onVersionUpdate(response.headers); + } + return response; + } } diff --git a/src/modules/auth-files.js b/src/modules/auth-files.js index 8bdce44..a1c9e11 100644 --- a/src/modules/auth-files.js +++ b/src/modules/auth-files.js @@ -724,16 +724,11 @@ export const authFilesModule = { this.vertexImportState.loading = true; this.updateVertexImportButtonState(); - const response = await fetch(`${this.apiUrl}/vertex/import`, { + const response = await this.apiClient.requestRaw('/vertex/import', { method: 'POST', - headers: { - 'Authorization': `Bearer ${this.managementKey}` - }, body: formData }); - this.updateVersionFromHeaders(response.headers); - if (!response.ok) { let errorMessage = `HTTP ${response.status}`; try { @@ -879,13 +874,7 @@ export const authFilesModule = { async downloadAuthFile(filename) { try { - const response = await fetch(`${this.apiUrl}/auth-files/download?name=${encodeURIComponent(filename)}`, { - headers: { - 'Authorization': `Bearer ${this.managementKey}` - } - }); - - this.updateVersionFromHeaders(response.headers); + const response = await this.apiClient.requestRaw(`/auth-files/download?name=${encodeURIComponent(filename)}`); if (!response.ok) { throw new Error(`HTTP ${response.status}`); @@ -1017,16 +1006,11 @@ export const authFilesModule = { const formData = new FormData(); formData.append('file', file, file.name); - const response = await fetch(`${this.apiUrl}/auth-files`, { + const response = await this.apiClient.requestRaw('/auth-files', { method: 'POST', - headers: { - 'Authorization': `Bearer ${this.managementKey}` - }, body: formData }); - this.updateVersionFromHeaders(response.headers); - if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error(errorData.error || `HTTP ${response.status}`); diff --git a/src/modules/config-editor.js b/src/modules/config-editor.js index 10295b8..d8e8195 100644 --- a/src/modules/config-editor.js +++ b/src/modules/config-editor.js @@ -152,16 +152,13 @@ export const configEditorModule = { const requestUrl = '/config.yaml'; try { - const response = await fetch(`${this.apiUrl}${requestUrl}`, { + const response = await this.apiClient.requestRaw(requestUrl, { method: 'GET', headers: { - 'Authorization': `Bearer ${this.managementKey}`, 'Accept': 'application/yaml' } }); - this.updateVersionFromHeaders(response.headers); - if (!response.ok) { const errorText = await response.text().catch(() => ''); const message = errorText || `HTTP ${response.status}`; @@ -227,18 +224,15 @@ export const configEditorModule = { }, async writeConfigFile(endpoint, yamlText) { - const response = await fetch(`${this.apiUrl}${endpoint}`, { + const response = await this.apiClient.requestRaw(endpoint, { method: 'PUT', headers: { - 'Authorization': `Bearer ${this.managementKey}`, 'Content-Type': 'application/yaml', 'Accept': 'application/json, text/plain, */*' }, body: yamlText }); - this.updateVersionFromHeaders(response.headers); - if (!response.ok) { const contentType = response.headers.get('content-type') || ''; let errorText = '';