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

如何在Laravel的Blade视图中调用ajax.php文件加载题库内容?

在Laravel Blade视图中正确调用AJAX题目接口的解决方案

问题的核心在于Laravel的架构和原生PHP环境不同:它依赖路由系统处理所有请求,直接放置在根目录的ajax.php无法被正确解析,而且Blade模板不会直接执行外部PHP文件的代码。我们需要把原有逻辑迁移到Laravel的MVC结构中,具体步骤如下:


1. 创建路由映射

首先在routes/web.php中添加一条POST路由,指向我们即将创建的控制器方法:

use App\Http\Controllers\QuizController;

Route::post('/quiz/fetch-question', [QuizController::class, 'fetchQuestion'])->name('quiz.fetch');
Route::post('/quiz/check-answer', [QuizController::class, 'checkAnswer'])->name('quiz.check'); // 用于验证答案更新分数

2. 迁移业务逻辑到控制器

生成QuizController并将原ajax.php的逻辑重构为Laravel风格(注意修复SQL注入风险、使用Laravel封装的数据库和Session):

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;

class QuizController extends Controller
{
    public function fetchQuestion(Request $request)
    {
        // 验证传入参数
        $request->validate([
            'next_id' => 'required|integer|min:0'
        ]);

        $nextId = $request->input('next_id');

        // 重置分数逻辑
        if ($nextId === 0) {
            Session::put('correct_score', 0);
            Session::put('not_correct_score', 0);
        }

        $totalQuestions = DB::table('questions')->count();

        // 检测是否完成所有题目
        if ($nextId >= $totalQuestions) {
            return view('quiz.results', [
                'correct' => Session::get('correct_score', 0),
                'wrong' => Session::get('not_correct_score', 0)
            ]);
        }

        // 安全获取下一题(参数化查询避免注入)
        $question = DB::table('questions')
            ->where('id', '>', $nextId)
            ->orderBy('id', 'asc')
            ->first();

        // 返回题目视图片段
        return view('quiz.question', compact('question', 'nextId'));
    }

    // 新增:验证答案并更新分数的方法
    public function checkAnswer(Request $request)
    {
        $request->validate([
            'question_id' => 'required|integer',
            'selected_answer' => 'required|integer|between:1,4'
        ]);

        $question = DB::table('questions')->find($request->question_id);
        if ($question->correct_answer == $request->selected_answer) {
            Session::increment('correct_score');
            return response()->json(['status' => 'correct']);
        } else {
            Session::increment('not_correct_score');
            return response()->json(['status' => 'wrong']);
        }
    }
}

3. 创建Blade视图片段

题目视图(resources/views/quiz/question.blade.php)

把原HTML改成Blade语法,修正单选按钮的name属性(确保同一题只能选一个选项):

<div id="question_{{ $question->id }}" class='question' data-next-question="{{ $question->id }}">
    <h2>{{ $question->id . '.' . $question->question_name }}</h2>
    <div class='align'>
        <input type="radio" value="1" id='radio1' name='answer'>
        <label id='ans1' for='radio1'>{{ $question->answer1 }}</label>
        <br/>
        <input type="radio" value="2" id='radio2' name='answer'>
        <label id='ans2' for='radio2'>{{ $question->answer2 }}</label>
        <br/>
        <input type="radio" value="3" id='radio3' name='answer'>
        <label id='ans3' for='radio3'>{{ $question->answer3 }}</label>
        <br/>
        <input type="radio" value="4" id='radio4' name='answer'>
        <label id='ans4' for='radio4'>{{ $question->answer4 }}</label>
    </div>
    <br/>
    <button class='butt'>Next!</button>
</div>

结果视图(resources/views/quiz/results.blade.php)

<div>
    <h2>Results:</h2>
    <p>Correct answers: {{ $correct }}</p>
    <p>Wrong answers: {{ $wrong }}</p>
    <button id="restart-quiz" class='butt'>Restart Quiz</button>
</div>

4. 在主Blade视图中编写AJAX逻辑

比如在resources/views/quiz/main.blade.php中,使用jQuery发送请求并渲染内容:

<div id="quiz-container"></div>

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
    $(document).ready(function() {
        // 初始化加载第一题
        loadQuestion(0);

        // 绑定Next按钮点击事件
        $(document).on('click', '.butt', function() {
            let nextId = $(this).closest('.question')?.data('next-question') || 0;
            // 处理重新开始按钮
            if ($(this).attr('id') === 'restart-quiz') nextId = 0;
            
            loadQuestion(nextId);
        });

        // 绑定单选按钮选择事件(验证答案)
        $(document).on('change', 'input[name="answer"]', function() {
            let questionId = $(this).closest('.question').attr('id').split('_')[1];
            let selectedAnswer = $(this).val();

            $.post("{{ route('quiz.check') }}", {
                question_id: questionId,
                selected_answer: selectedAnswer,
                _token: "{{ csrf_token() }}"
            }, function(res) {
                // 可选:给用户反馈,比如高亮正确/错误选项
            });
        });

        // 通用加载题目函数
        function loadQuestion(nextId) {
            $.post("{{ route('quiz.fetch') }}", {
                next_id: nextId,
                _token: "{{ csrf_token() }}"
            }, function(html) {
                $('#quiz-container').html(html);
            });
        }
    });
</script>

关键注意事项

  • CSRF保护:Laravel默认启用CSRF保护,所有POST请求必须携带_token参数,否则会被拦截。
  • SQL注入防护:原代码直接拼接SQL存在注入风险,Laravel的查询构建器会自动处理参数绑定,一定要使用这种方式。
  • Session管理:Laravel已经封装了Session,无需手动调用session_start()。
  • 单选按钮name属性:原代码中每个单选按钮的name不同,会导致用户可以多选同一题的多个选项,统一改为name="answer"即可修复。

内容的提问来源于stack exchange,提问作者Zubair Nazer Oliyat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:29:47