You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 8应用AJAX加载评论触发500错误的原因与修复

Laravel 8 博客无限滚动评论加载500内部服务器错误排查与修复

问题背景

基于Laravel 8开发的博客应用,文章详情页实现了评论展示及无限滚动加载功能:页面初始加载前10条评论,滚动时通过AJAX请求https://larablog.com/load_comments加载更多内容,但触发500内部服务器错误。


1. 错误原因

结合Laravel此类场景的常见报错及日志信息,核心原因通常为以下一种或多种:

  • 文章ID参数缺失:load_comments路由未传递文章ID,控制器无法定位对应文章,调用comments()关联查询时抛出Call to a member function comments() on null异常。
  • CSRF验证失败:AJAX请求未携带CSRF令牌,Laravel的CSRF中间件拦截请求并抛出异常。
  • 分页参数处理错误:控制器未正确接收或处理分页page参数,导致Eloquent查询生成无效SQL语句。
  • 视图变量未传递:返回comments-list.blade.php时未传递必要变量(如评论集合、文章实例),引发视图渲染错误。

2. 最可靠的修复方案

按优先级执行以下修复步骤:

修复1:确保路由与控制器正确接收文章ID

  • 路由定义(web.php):为load_comments路由添加文章ID参数,启用路由模型绑定:
    Route::get('/load_comments/{article}', [ArticlesController::class, 'loadComments'])->name('comments.load');
    
  • 控制器方法(ArticlesController.php):通过路由模型绑定自动获取文章实例,正确处理分页查询:
    public function loadComments(Article $article, Request $request)
    {
        // 初始已加载第1页,默认从第2页开始加载
        $currentPage = $request->input('page', 2);
        // 查询对应文章的评论,按创建时间倒序分页
        $comments = $article->comments()
                            ->orderBy('created_at', 'desc')
                            ->paginate(10, ['*'], 'page', $currentPage);
    
        return view('comments-list', compact('comments', 'article'));
    }
    

修复2:AJAX请求携带CSRF令牌

修改infinite-comments.js,在请求中加入CSRF令牌:

// 获取页面头部的CSRF令牌
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
// 假设文章ID已存储在页面的data属性中
const articleId = document.getElementById('article-detail').dataset.articleId;
let nextPage = 2;

// 滚动触发逻辑
window.addEventListener('scroll', () => {
    if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 100) {
        fetch(`/load_comments/${articleId}?page=${nextPage}`, {
            headers: {
                'X-CSRF-TOKEN': csrfToken,
                'Accept': 'text/html'
            }
        })
        .then(response => {
            if (!response.ok) throw new Error('请求失败');
            return response.text();
        })
        .then(html => {
            document.getElementById('comments-container').insertAdjacentHTML('beforeend', html);
            nextPage++;
        })
        .catch(err => console.error(err));
    }
});

同时确保文章详情页头部已包含CSRF元标签:

<meta name="csrf-token" content="{{ csrf_token() }}">

修复3:确保视图变量正确传递与使用

修改comments-list.blade.php,确保使用的变量均已从控制器传递:

@foreach($comments as $comment)
    <div class="comment-card mb-3">
        <div class="comment-author">{{ $comment->author_name }}</div>
        <div class="comment-content mt-1">{{ $comment->content }}</div>
        <!-- 评论回复展示逻辑 -->
        @if($comment->replies->isNotEmpty())
            <div class="replies mt-2 pl-4">
                @foreach($comment->replies as $reply)
                    <div class="reply-card">{{ $reply->content }}</div>
                @endforeach
            </div>
        @endif
    </div>
@endforeach

<!-- 标记是否还有更多评论 -->
@if(!$comments->hasMorePages())
    <div class="no-more-comments text-center py-3">没有更多评论了</div>
@endif

修复4:验证分页逻辑正确性

  • 确认AJAX请求中page参数从第2页开始递增,避免与初始加载的第1页冲突。
  • 控制器中使用paginate()的第四个参数指定当前页码,确保分页查询正确。

内容的提问来源于stack exchange,提问作者Razvan Zamfir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 12:07:42