Download src/services/api.js from ahutchen/music: direct link, hf CLI and curl.
- Browser
- Download file 2.93 kB
-
https://huggingface.co/spaces/ahutchen/music/resolve/main/src/services/api.js
- Command line
-
hf download hf://spaces/ahutchen/music/src/services/api.js
-
curl -L -o api.js https://huggingface.co/spaces/ahutchen/music/resolve/main/src/services/api.js
2.93 kB
| // 基础API请求封装 | |
| class ApiClient { | |
| constructor(baseURL = '', options = {}) { | |
| this.baseURL = baseURL | |
| this.timeout = options.timeout || 30000 // 改为30秒 | |
| this.headers = { | |
| // 不要默认设置Content-Type,避免触发预检请求 | |
| ...options.headers | |
| } | |
| } | |
| // 基础请求方法 | |
| async request(url, options = {}) { | |
| const controller = new AbortController() | |
| const timeoutId = setTimeout(() => controller.abort(), this.timeout) | |
| try { | |
| const fullUrl = url.startsWith('http') ? url : `${this.baseURL}${url}` | |
| // 对于所有请求,都不要添加默认的Content-Type头部,避免触发预检请求 | |
| const fetchOptions = { | |
| signal: controller.signal, | |
| ...options | |
| } | |
| const response = await fetch(fullUrl, fetchOptions) | |
| clearTimeout(timeoutId) | |
| if (!response.ok) { | |
| throw new Error(`HTTP ${response.status}: ${response.statusText}`) | |
| } | |
| const contentType = response.headers.get('content-type') | |
| if (contentType && contentType.includes('application/json')) { | |
| return await response.json() | |
| } | |
| return await response.text() | |
| } catch (error) { | |
| clearTimeout(timeoutId) | |
| if (error.name === 'AbortError') { | |
| throw new Error('请求超时') | |
| } | |
| // 处理CORS错误,重新抛出错误让上层处理 | |
| if (error.toString().includes('CORS') || error.toString().includes('Failed to fetch')) { | |
| console.error('CORS错误:', url, error) | |
| throw new Error('网络请求失败,请检查网络连接') | |
| } | |
| throw error | |
| } | |
| } | |
| // GET请求 | |
| get(url, params = {}) { | |
| let fullUrl = url.startsWith('http') ? url : `${this.baseURL}${url}` | |
| // 统一使用手动构建查询字符串的方式,避免URL对象可能带来的问题 | |
| const queryString = Object.entries(params) | |
| .filter(([_, value]) => value !== undefined && value !== null) | |
| .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`) | |
| .join('&') | |
| fullUrl = queryString ? `${fullUrl}?${queryString}` : fullUrl | |
| return this.request(fullUrl, { | |
| method: 'GET' | |
| }) | |
| } | |
| // POST请求 | |
| post(url, data = {}) { | |
| return this.request(url, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| ...this.headers | |
| }, | |
| body: JSON.stringify(data) | |
| }) | |
| } | |
| // PUT请求 | |
| put(url, data = {}) { | |
| return this.request(url, { | |
| method: 'PUT', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| ...this.headers | |
| }, | |
| body: JSON.stringify(data) | |
| }) | |
| } | |
| // DELETE请求 | |
| delete(url) { | |
| return this.request(url, { | |
| method: 'DELETE' | |
| }) | |
| } | |
| } | |
| // 创建默认实例 | |
| export const apiClient = new ApiClient() | |
| // 导出类以便创建自定义实例 | |
| export { ApiClient } |