/**
 * 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 实例,包含要上传的表单字段(例如评论内容、昵称等)。
  • 实现步骤:
    1. 使用 POST 方法并将 formData 放入请求体,带上 'X-Requested-With' 头。
    2. 获取响应头中的 commentCount(可用于更新页面上的评论数量)。
    3. 检查响应的 content-type,如果包含 'application/json',认为返回的是 JSON,调用 response.json():
      • 在这种情况里函数立即返回 { success: false, msg: data.msg || '提交失败' }(注意:这里假定 JSON 表示出错情况)。
    4. 如果不是 JSON,则先把响应读成文本(response.text()),然后尝试将文本解析为 JSON:
      • 如果解析成功且解析结果中包含 success === false,则认为是错误,返回 { success: false, msg: json.msg }。
      • 如果解析失败(抛异常),则认为响应是 HTML(即成功返回的评论片段),最终返回 { success: true, html, commentCount }。
    5. 在任何网络或运行时异常下,打印错误并返回 { success: false, msg: '网络请求失败' }。
  • 返回值(Promise):一个对象,常见属性:
    • success: boolean
    • html: string (成功返回的 HTML 片段)
    • msg: string (失败时的提示)
    • commentCount: string|null

loadComments(url)

  • 目的:获取评论列表片段(刷新或翻页)。
  • 参数:
    • url:查询地址(字符串)。
  • 实现步骤:
    1. 使用 GET 方法请求指定 url,带上 'X-Requested-With' 头。
    2. 如果 response.ok 为 false(HTTP 状态不是 2xx),抛出错误。
    3. 读取响应头中的 commentCount。
    4. 读取响应文本作为 html,并返回 { success: true, html, commentCount }。
    5. 捕获异常时打印错误并返回 { 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 做相应更新。
评论加载中...