refactor(api): add raw request helper and centralize headers

This commit is contained in:
hkfires
2025-11-21 10:16:06 +08:00
parent a6344a6a61
commit e58d462153
3 changed files with 35 additions and 32 deletions

View File

@@ -8,6 +8,21 @@ export class ApiClient {
this.setApiBase(apiBase); 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) { normalizeBase(input) {
let base = (input || '').trim(); let base = (input || '').trim();
if (!base) return ''; if (!base) return '';
@@ -37,11 +52,7 @@ export class ApiClient {
async request(endpoint, options = {}) { async request(endpoint, options = {}) {
const url = `${this.apiUrl}${endpoint}`; const url = `${this.apiUrl}${endpoint}`;
const headers = { const headers = this.buildHeaders(options);
'Authorization': `Bearer ${this.managementKey}`,
'Content-Type': 'application/json',
...options.headers
};
const response = await fetch(url, { const response = await fetch(url, {
...options, ...options,
@@ -59,4 +70,18 @@ export class ApiClient {
return await response.json(); 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;
}
} }

View File

@@ -724,16 +724,11 @@ export const authFilesModule = {
this.vertexImportState.loading = true; this.vertexImportState.loading = true;
this.updateVertexImportButtonState(); this.updateVertexImportButtonState();
const response = await fetch(`${this.apiUrl}/vertex/import`, { const response = await this.apiClient.requestRaw('/vertex/import', {
method: 'POST', method: 'POST',
headers: {
'Authorization': `Bearer ${this.managementKey}`
},
body: formData body: formData
}); });
this.updateVersionFromHeaders(response.headers);
if (!response.ok) { if (!response.ok) {
let errorMessage = `HTTP ${response.status}`; let errorMessage = `HTTP ${response.status}`;
try { try {
@@ -879,13 +874,7 @@ export const authFilesModule = {
async downloadAuthFile(filename) { async downloadAuthFile(filename) {
try { try {
const response = await fetch(`${this.apiUrl}/auth-files/download?name=${encodeURIComponent(filename)}`, { const response = await this.apiClient.requestRaw(`/auth-files/download?name=${encodeURIComponent(filename)}`);
headers: {
'Authorization': `Bearer ${this.managementKey}`
}
});
this.updateVersionFromHeaders(response.headers);
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP ${response.status}`); throw new Error(`HTTP ${response.status}`);
@@ -1017,16 +1006,11 @@ export const authFilesModule = {
const formData = new FormData(); const formData = new FormData();
formData.append('file', file, file.name); formData.append('file', file, file.name);
const response = await fetch(`${this.apiUrl}/auth-files`, { const response = await this.apiClient.requestRaw('/auth-files', {
method: 'POST', method: 'POST',
headers: {
'Authorization': `Bearer ${this.managementKey}`
},
body: formData body: formData
}); });
this.updateVersionFromHeaders(response.headers);
if (!response.ok) { if (!response.ok) {
const errorData = await response.json().catch(() => ({})); const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.error || `HTTP ${response.status}`); throw new Error(errorData.error || `HTTP ${response.status}`);

View File

@@ -152,16 +152,13 @@ export const configEditorModule = {
const requestUrl = '/config.yaml'; const requestUrl = '/config.yaml';
try { try {
const response = await fetch(`${this.apiUrl}${requestUrl}`, { const response = await this.apiClient.requestRaw(requestUrl, {
method: 'GET', method: 'GET',
headers: { headers: {
'Authorization': `Bearer ${this.managementKey}`,
'Accept': 'application/yaml' 'Accept': 'application/yaml'
} }
}); });
this.updateVersionFromHeaders(response.headers);
if (!response.ok) { if (!response.ok) {
const errorText = await response.text().catch(() => ''); const errorText = await response.text().catch(() => '');
const message = errorText || `HTTP ${response.status}`; const message = errorText || `HTTP ${response.status}`;
@@ -227,18 +224,15 @@ export const configEditorModule = {
}, },
async writeConfigFile(endpoint, yamlText) { async writeConfigFile(endpoint, yamlText) {
const response = await fetch(`${this.apiUrl}${endpoint}`, { const response = await this.apiClient.requestRaw(endpoint, {
method: 'PUT', method: 'PUT',
headers: { headers: {
'Authorization': `Bearer ${this.managementKey}`,
'Content-Type': 'application/yaml', 'Content-Type': 'application/yaml',
'Accept': 'application/json, text/plain, */*' 'Accept': 'application/json, text/plain, */*'
}, },
body: yamlText body: yamlText
}); });
this.updateVersionFromHeaders(response.headers);
if (!response.ok) { if (!response.ok) {
const contentType = response.headers.get('content-type') || ''; const contentType = response.headers.get('content-type') || '';
let errorText = ''; let errorText = '';