Initial commit: MyBlog full stack blog
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
/* =====================================================================
|
||||
* 网络层(api.js)
|
||||
* 统一调用 /api/* 接口;localStorage 只保存 token 与 username(绝不保存密码)。
|
||||
* ===================================================================== */
|
||||
|
||||
export class ApiError extends Error {
|
||||
constructor(message, status) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
|
||||
export async function api(path, { method = "GET", body } = {}) {
|
||||
const headers = { "Content-Type": "application/json" };
|
||||
const token = localStorage.getItem("token");
|
||||
if (token) headers["Authorization"] = `Bearer ${token}`;
|
||||
let res;
|
||||
try {
|
||||
res = await fetch(path, { method, headers, body: body === undefined ? undefined : JSON.stringify(body) });
|
||||
} catch (err) {
|
||||
throw new ApiError("网络请求失败,请稍后再试", 0);
|
||||
}
|
||||
let json = null;
|
||||
try { json = await res.json(); } catch (err) { /* 忽略非 JSON 响应 */ }
|
||||
if (!json || typeof json.success === "undefined") {
|
||||
throw new ApiError(`服务器响应异常(${res.status})`, res.status);
|
||||
}
|
||||
if (!json.success) throw new ApiError(json.message || "请求失败", res.status);
|
||||
return json.data;
|
||||
}
|
||||
|
||||
// multipart 表单提交(普通字段 + 单个文件),用于项目管理等
|
||||
export async function uploadForm(path, fields = {}, file = null, method = "POST") {
|
||||
const form = new FormData();
|
||||
for (const [key, value] of Object.entries(fields)) {
|
||||
if (value !== undefined && value !== null && value !== "") form.append(key, String(value));
|
||||
}
|
||||
if (file) form.append("file", file);
|
||||
const headers = {};
|
||||
const token = localStorage.getItem("token");
|
||||
if (token) headers["Authorization"] = `Bearer ${token}`;
|
||||
const res = await fetch(path, { method, headers, body: form });
|
||||
let json = null;
|
||||
try { json = await res.json(); } catch (err) { /* 忽略非 JSON 响应 */ }
|
||||
if (!json || !json.success) throw new ApiError((json && json.message) || "操作失败", res.status);
|
||||
return json.data;
|
||||
}
|
||||
|
||||
// multipart 上传(头像/图片/项目文件),返回 {url, filename, size}
|
||||
export async function uploadFile(path, file, extra = {}) {
|
||||
const form = new FormData();
|
||||
form.append("file", file);
|
||||
// extra:附加字段(如上传文档时携带文章分区 category,供后端校验)
|
||||
for (const [key, value] of Object.entries(extra)) form.append(key, value);
|
||||
const headers = {};
|
||||
const token = localStorage.getItem("token");
|
||||
if (token) headers["Authorization"] = `Bearer ${token}`;
|
||||
const res = await fetch(path, { method: "POST", headers, body: form });
|
||||
let json = null;
|
||||
try { json = await res.json(); } catch (err) { /* 忽略非 JSON 响应 */ }
|
||||
if (!json || !json.success) throw new ApiError((json && json.message) || "上传失败", res.status);
|
||||
return json.data;
|
||||
}
|
||||
Reference in New Issue
Block a user