【问题标题】:Laravel - do not continue after form validator if ajax requestLaravel - 如果 ajax 请求,不要在表单验证器之后继续
【发布时间】:2018-04-19 02:16:33
【问题描述】:

我想创建一个 ajax 表单验证来验证表单数据并在真正提交表单之前给用户即时反馈。

为此,我在表单提交上添加了一个 javascript 函数:

<form id="x" onsubmit="return dosubmit(this)" action="{{ url('/x') }}" method="POST">

<script>
    function dosubmit(form) {
        $.ajax({
            url: $(form).attr('action'),
            type: 'post',
            data: $(form).serializeArray()
        }).done(function (data) {
            form.submit();
        }).fail(function (data) {
            alert('error');
        });
        return false;
    }
</script>

我自定义了一个表单验证器请求:

class X extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'name' => 'required',
        ];
    }
}

当我的 ajax 请求失败时,一切正常。我的表单验证器以 json 格式返回错误,我可以将其显示给用户。问题是,当它成功时,它实际上两次发布数据 - 第一次来自 ajax 请求,第二次因为我在 ajax 请求成功后调用 form.submit() 。因为我想在提交后重定向用户,我实际上只希望第二次提交到达控制器。这意味着我必须在验证后停止 ajax 请求。我目前的解决方法是我的控制器中有这样一行:

public function store(X $request)
{
    if ($request->ajax()) {
        return;
    }

    // only actual request reaches here
}

这行得通,但它并不漂亮。我不喜欢在我的控制器中包含这条线。如果我可以在我的请求验证器中做类似的事情,我会很高兴,但我找不到从那里验证后返回的好方法。有什么想法我该如何做到这一点?

【问题讨论】:

    标签: javascript php laravel laravel-5 laravel-5.4


    【解决方案1】:

    你可以这样试试:

    <script>
        function dosubmit(form) {
            $.ajax({
                async: false,    // make ajax not async
                url: $(form).attr('action'),
                type: 'post',
                data: $(form).serializeArray()
            }).done(function (data) {
                form.submit();
            }).fail(function (data) {
                alert('error');
            });
            return false;
        }
    </script>
    

    并且在控制器中只需正常执行此操作...

    if ($request->ajax()) { 返回; }

    如果可行,请提供反馈...我也很感兴趣。

    【讨论】:

    • 恐怕你误解了这个问题。
    • 我的理解是这样的:您只想提交一次表单并在验证失败时使用成功消息或错误消息重定向?对吗?
    【解决方案2】:

    您的问题可以通过更改 javascript 代码来解决。我认为您对 deferred.done() 方法的作用感到困惑。在您的代码中,您提交了两次表单。

    让我分解你的 js 脚本,done() 方法用于在提交表单后执行进一步的操作 (Please refer)。

    在您的代码中,第一个$.ajax 实际上将您的表单提交到后端(在这里,如果后端有任何错误,您可以在fail 部分处理它们)。如果表单成功提交且没有任何错误,那么在done 部分中,您可以定义关于表单提交成功后要执行的操作或操作。

    您没有定义成功提交表单后要执行的操作,而是再次重新提交相同的表单。因此,从 js 代码中删除该部分以及您在后端完成的解决方法。

    function dosubmit(form) {
        $.ajax({
            url: $(form).attr('action'),
            type: 'post',
            data: $(form).serializeArray()
        }).done(function (data) {
            // form.submit();
            // handle successful form submission
        }).fail(function (data) {
            alert('error');
        });
        return false;
    }
    

    【讨论】:

    • 是的,我明白我在做什么,并且是有意的。第一次提交只是为了验证数据,如果一切正确,那么我想在没有 ajax 和页面刷新的情况下再次提交表单。问题是我如何才能阻止第一个请求实际提交数据并仅对其进行验证。
    • @user1985273 如果您想在第一次提交时进行验证,那么您需要创建一个单独的路由来验证控制器中的表单(在 Ajax 的 URL 部分添加该路由);然后提交表格。我认为您不想使用任何客户端验证,对吧?
    猜你喜欢
    • 1970-01-01
    • 2020-08-20
    • 2017-02-23
    • 2023-04-02
    • 2023-03-22
    • 2016-09-02
    • 1970-01-01
    • 2016-05-23
    相关资源
    最近更新 更多