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

Yii框架Ajax表单提交触发两次请求的问题排查与解决

问题分析与解决

一、Ajax请求触发两次的原因

  1. Yii ActiveForm内置校验请求:你开启了enableAjaxValidation = true和validateOnSubmit = true,这会让Yii在表单提交时自动发起一次Ajax请求做模型校验。
  2. 自定义提交事件请求:你额外绑定了表单的submit事件,手动发起了一次Ajax提交,两者叠加导致两次请求。

二、阻止重复请求的几种方案

方案1:关闭Yii内置的提交时校验(最简单)

如果不需要提交前的Ajax模型校验,直接修改ActiveForm配置:

$form = ActiveForm::begin([
    'id' => $model->formName(),
    'enableAjaxValidation' => false, // 关闭Ajax校验
    'enableClientValidation'=> false,
    'validateOnBlur' => false,
    'validateOnChange' => false,
    'validateOnSubmit' => false, // 关闭提交时自动校验
    'options' => ['autocomplete' => 'off'],
]);

这样就只有你自定义的submit事件会发起请求。

方案2:保留Ajax校验,复用Yii事件逻辑

如果需要保留提交前校验,不要自己绑定submit事件,改用Yii ActiveForm的beforeSubmit事件,在校验通过后再发起提交:

$(document).ready(function () {  
    var $form = $("#<?= $model->formName() ?>");
    $form.on("beforeSubmit", function (event) {
        event.preventDefault();
        $.ajax({
            "type":"POST",
            "url":$form.attr('action'),
            "data":$form.serialize(),
            "dataType":"json",
            "cache": false, // 表单提交建议关闭缓存
            "success":function(data){
                if (data.tax) {
                    $("#tax").html(data.tax);   
                }
            }                    
        });
        return false;       
    });
});

后端保持enableAjaxValidation = true和validateOnSubmit = true即可,Yii会先完成校验,通过后才触发beforeSubmit事件。

方案3:在自定义事件中区分校验触发的提交

Yii触发submit时会传递messages参数,可通过该参数判断是否为校验导致的提交,只处理自定义逻辑:

$(document).ready(function () {  
    var $form = $("#<?= $model->formName() ?>");
    $form.on("submit", function (event, messages) {
        // 存在messages说明是Yii校验触发的submit,直接返回
        if (messages) return;
        
        event.preventDefault();
        event.stopImmediatePropagation(); 
        $.ajax({
            "type":"POST",
            "url":$form.attr('action'),
            "data":$form.serialize(),
            "dataType":"json",
            "cache": false,
            "success":function(data){
                $("#tax").html(data.tax);   
            }                    
        });
        return false;       
    });
});

三、正确更新计算结果到指定div的问题

你后端执行calculatetax()后直接die;,没有返回JSON数据,前端根本拿不到data.tax。需要修改后端代码,返回包含计算结果的JSON响应:

if ($model->validate())
{
    $taxResult = $this->calculatetax(); // 假设calculatetax()返回计算结果
    Yii::$app->response->format = Response::FORMAT_JSON;
    return ['tax' => $taxResult];
    // 去掉die;,让Yii正常输出JSON响应
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:12:12