/**
* Comment API Module
* Handles server communication
*/
export class CommentApi {
/**
* Post a new comment
* @param {string} url - The action URL
* @param {FormData} formData - The form data
* @returns {Promise<{success: boolean, html?: string, msg?: string, commentCount?: string}>}
*/
async postComment(url, formData) {
try {
const response = await fetch(url, {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
});
const commentCount = response.headers.get('commentCount');
// Check content type to determine if JSON or HTML
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
const data = await response.json();
return { success: false, msg: data.msg || '提交失败' };
}
const html = await response.text();
// In the legacy controller, it might return a JSON with {success: false} on error,
// or HTML on success. The old JS handled this by checking property "success".
// Since we receive text, we might need to try parsing it as JSON first if it looks like it.
try {
const json = JSON.parse(html);
if (json && json.success === false) {
return { success: false, msg: json.msg };
}
} catch (e) {
// Not JSON, assume HTML success
}
return { success: true, html, commentCount };
} catch (error) {
console.error('Comment Post Error:', error);
return { success: false, msg: '网络请求失败' };
}
}
/**
* Load comments (Refresh or Paging)
* @param {string} url - The URL to fetch
* @returns {Promise<{success: boolean, html?: string, commentCount?: string}>}
*/
async loadComments(url) {
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const commentCount = response.headers.get('commentCount');
const html = await response.text();
return { success: true, html, commentCount };
} catch (error) {
console.error('Comment Load Error:', error);
return { success: false };
}
}
}
⚠⚠ 以下内容为AI分析的结果,请根据实际情况进行判断。
这段代码定义了一个名为 CommentApi 的 ES6 类,用于与后端就评论相关的接口交互,包含两个异步方法:postComment(提交新评论)和 loadComments(加载/刷新或翻页获取评论)。下面按功能与实现细节解释:
总体行为
- 使用浏览器的 fetch API 发起 HTTP 请求。
- 请求都带了自定义头部 'X-Requested-With': 'XMLHttpRequest',通常用于告诉服务器这是一个 AJAX 请求。
- 从响应头中读取名为 commentCount 的自定义头,用来返回当前评论数(返回值是字符串或 null)。
- 捕获错误并在控制台打印,返回统一的失败结构。
postComment(url, formData)
- 目的:向后端提交一个新评论表单。
- 参数:
- url:提交地址(字符串)。
- formData:FormData 实例,包含要上传的表单字段(例如评论内容、昵称等)。
- 实现步骤:
- 使用 POST 方法并将 formData 放入请求体,带上 'X-Requested-With' 头。
- 获取响应头中的 commentCount(可用于更新页面上的评论数量)。
- 检查响应的 content-type,如果包含 'application/json',认为返回的是 JSON,调用 response.json():
- 在这种情况里函数立即返回 { success: false, msg: data.msg || '提交失败' }(注意:这里假定 JSON 表示出错情况)。
- 如果不是 JSON,则先把响应读成文本(response.text()),然后尝试将文本解析为 JSON:
- 如果解析成功且解析结果中包含 success === false,则认为是错误,返回 { success: false, msg: json.msg }。
- 如果解析失败(抛异常),则认为响应是 HTML(即成功返回的评论片段),最终返回 { success: true, html, commentCount }。
- 在任何网络或运行时异常下,打印错误并返回 { success: false, msg: '网络请求失败' }。
- 返回值(Promise):一个对象,常见属性:
- success: boolean
- html: string (成功返回的 HTML 片段)
- msg: string (失败时的提示)
- commentCount: string|null
loadComments(url)
- 目的:获取评论列表片段(刷新或翻页)。
- 参数:
- url:查询地址(字符串)。
- 实现步骤:
- 使用 GET 方法请求指定 url,带上 'X-Requested-With' 头。
- 如果 response.ok 为 false(HTTP 状态不是 2xx),抛出错误。
- 读取响应头中的 commentCount。
- 读取响应文本作为 html,并返回 { success: true, html, commentCount }。
- 捕获异常时打印错误并返回 { success: false }。
- 返回值(Promise):一个对象,常见属性:
- success: boolean
- html: string (成功时)
- commentCount: string|null
需要注意和可能的改进点
- postComment 中对 JSON 的处理假定 JSON 总是表示错误,并直接返回 success: false;如果服务器在成功时返回 JSON(而非 HTML),当前代码会把它当作错误。应根据后端的约定明确处理成功/失败的 JSON 格式。
- postComment 没有检查 response.ok(HTTP 状态),直接根据 content-type 与文本内容判断。建议也检查 response.ok,以便更明确地处理 4xx/5xx。
- commentCount 从响应头读取后直接返回字符串,可能需要在前端转换为整数(parseInt)再使用。
- content-type 的比较使用 includes 是合理的,但注意大小写可能不同(headers.get 返回的通常是小写),当前实现可以正常工作。
- 没有设置 credentials(如需携带 cookie 的登录态,可能需要 { credentials: 'same-origin' } 或 'include')。
- 没有实现请求超时(fetch 本身没有内置超时,需要用 AbortController)。
- 错误信息对用户呈现时可能需要更友好的本地化与处理。
总结
- 这个类封装了评论相关的两个 HTTP 操作:提交评论和加载评论片段,处理了常见的返回情况(HTML 或 JSON),并将结果以统一对象形式返回,方便上层 UI 调用并根据 success/html/msg/commentCount 做相应更新。
评论加载中...