【问题标题】:Laravel Form validation redirects back to home page upon form errors instead of staying on same pageLaravel 表单验证在表单错误时重定向回主页,而不是停留在同一页面上
【发布时间】:2020-12-14 04:17:54
【问题描述】:

我有一个联系表格,提交后会成功发送到数据库。问题是,当我在我的网页上检查验证时,使用 Larvael $error 验证正确显示错误,问题是我的网页总是在出现错误时重定向回主页,而不是页面保持静止并显示错误。我必须继续向下滚动到我的联系表所在的位置才能查看错误;这对我未来的用户来说会很烦人。如果出现错误,如何让页面保持原样?注意:当表单有效并提交时,我的页面会正确重定向,这不是问题。 NOTE-2:我创建了一个单页网页,导航链接将您带到该网页,没有重定向。相反,它是一个 HTML 页面。

Web.php

Route::get('/', 'HomeController@index')->name('home');
Route::post('/contact/submit', 'MessagesController@submit');

MessagesController.php

namespace App\Http\Controllers;

use App\Message;
use Illuminate\Http\Request;

class MessagesController extends Controller
{
    public function submit(Request $request)
    {
        $validatedData = $request->validate([
            'name' => 'required|min:2',
            'email' => 'required|max:255',
            'phonenumber' => 'required|min:10|max:10',
            'message' => 'required|min:5',
        ]);

        Message::create($validatedData);

        return redirect('/')->with('success', 'Your message has been 
            successfully sent. We will reach out to you soon');
    }
}

contact.blade.php

{{--CONTACT FORM--}}
<section id="contact">
    <div class="container-fluid padding">
        <div class="row text-center padding">
            <div class="col-12">
                <h2 class="lead display-3">Contact Us</h2>
                <hr class="my-4">

                <form action="/contact/submit" method="POST">
                    @csrf
                    <div class="field">
                        <label for="name" class="label">Name</label>

                        <div class="control">
                            <input type="text" class="input {{$errors->has('name') ? 'is-danger' : 'is-success'}}"
                                   name="name" placeholder="Project Title" value="{{old('name')}}">
                        </div>
                    </div>

                    <div class="field">
                        <label for="name" class="label">Email</label>

                        <div class="control">
                            <input type="text" class="input {{$errors->has('email') ? 'is-danger' : 'is-success'}}"
                                   name="email" placeholder="Project Title" value="{{old('email')}}">
                        </div>
                    </div>

                    <div class="field">
                        <label for="name" class="label">Phone Number</label>

                        <div class="control">
                            <input type="text"
                                   class="input {{$errors->has('phonenumber') ? 'is-danger' : 'is-success'}}"
                                   name="phonenumber" placeholder="Project Title" value="{{old('phonenumber')}}">
                        </div>
                    </div>

                    <div class="field">
                        <label for="message" class="label">Message</label>
                        <div class="control">
                            <textarea name="message"
                                      class="textarea {{$errors->has('message') ? 'is-danger' : 'is-success'}}"
                                      placeholder="Project description">{{old('message')}}</textarea>
                        </div>
                    </div>

                    <div class="field">
                        <div class="control">
                            <button type="submit" class="button is-link">Create Project</button>
                        </div>
                    </div>

                    <!--Errors variable used from form validation -->
                    @if($errors->any())
                        <div class="notification is-danger">
                            <ul>
                                @foreach($errors->all() as $error)
                                    <li>{{$error}}</li>
                                @endforeach
                            </ul>
                        </div>
                    @endif
                </form>
            </div>
        </div>
    </div>
</section>

【问题讨论】:

  • 我尝试用“return back()-with()....”替换我的控制器中当前的 return 语句,但是当我尝试提交无效表单时页面仍会转到主页.错误消息正确显示,但我必须一直向下滚动页面才能查看错误消息。

标签: laravel laravel-blade


【解决方案1】:

您需要创建一个手动验证器,以便在验证失败时控制重定向(我认为这是您遇到的问题)。

public function submit(Request $request)
    {
        $validator = Validator::make($request->all(),[
            'name' => 'required|min:2',
            'email' => 'required|max:255',
            'phonenumber' => 'required|min:10|max:10',
            'message' => 'required|min:5',
        ]);

        if ($validator->fails()) {
            return redirect(url()->previous() .'#contact')
                    ->withErrors($validator)
                    ->withInput();
        }

        Message::create($request->all());

        return redirect('/')->with('success', 'Your message has been 
            successfully sent. We will reach out to you soon');
    }

【讨论】:

  • 我收到一条错误消息:Class App\Http\Controllers\Request 不存在
  • 这有帮助 :) 除了您的代码之外,我所要做的就是导入必要的类:即(使用 Illuminate\Http\Request;使用 Illuminate\Support\Facades\Validator;)谢谢!跨度>
  • 这很好,但这不是你应该做的@PA-GW。将验证逻辑与控制器分开。以后你会感谢我的。
【解决方案2】:

首先,将错误移到表单顶部,以便您查看。

<form action="/contact/submit" method="POST">
    @csrf
    @if($errors->any())
        <div class="notification is-danger">
            <ul>
                @foreach($errors->all() as $error)
                    <li>{{$error}}</li>
                @endforeach
            </ul>
        </div>
    @endif

处理验证的更好方法是使用表单请求将其分开。

php artisan make:request SendMessageRequest
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class SendMessageRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }
    
    public function rules()
    {
        return [
            'name' => 'required|min:2',
            'email' => 'required|max:255',
            'phonenumber' => 'required|min:10|max:10',
            'message' => 'required|min:5',
        ];
    }
}

如果验证失败,将自动生成重定向响应,将用户送回之前的位置。

现在更新您的控制器。

use App\Http\Requests\SendMessageRequest;
use App\Message;

class MessagesController extends Controller
{
    public function submit(SendMessageRequest $request)
    {
        Message::create($request->validated());

        return redirect('/')->with('success', 'Your message has been
            successfully sent. We will reach out to you soon');
    }
}

您可以使用Validatorback() 重定向将验证留在控制器中,但第一种方法更好。

public function submit(Request $request)
{
    $validator = Validator::make($request->all(), [
        'name' => 'required|min:2',
        'email' => 'required|max:255',
        'phonenumber' => 'required|min:10|max:10',
        'message' => 'required|min:5',
    ]);

    if ($validator->fails()) {
        return back()->withInput()->withErrors($validator);
    }

    Message::create($request->all());

    return redirect('/')->with('success,' 'Your message has been
        successfully sent. We will reach out to you soon');
}

【讨论】:

  • 你好,我实现了你的代码,看起来很干净,但是当我通过提交一个空表单去测试验证时,我得到一个 403 页面(禁止,未经授权),有什么建议吗?
  • 嗨,Karl,正如我上面所说,我在使用您的代码时遇到了 403 Forbidden 错误。我想实现您的代码,但如何通过 403?我尝试在 m 项目根目录中创建一个 htaccess 文件,并从我的公共 htaccess 文件中添加了 ifmodule 代码,但没有运气。有什么建议吗?谢谢。
  • 在 laravel.log 里写了什么?
  • 我让您的代码在没有 403 错误的情况下正常工作,但它仍然将我重定向回主页,而不是返回我的 html 页面的#contact 部分。你的方式有点干净,但我需要页面在页面的#contact部分显示错误而不重定向到主页,然后必须向下滚动到#contact。你有办法让你的代码留在页面的同一部分并显示错误吗?
  • @PA-GW 在授权方法中返回 true。默认为假。
猜你喜欢
  • 1970-01-01
  • 2022-10-17
  • 2018-01-05
  • 2020-03-23
  • 2013-06-24
  • 2012-09-22
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
相关资源
最近更新 更多