вопросы пишите мне в телеграмм +375298176892
можно скачать офлайн версию сайта: code.mu old.code.mu

Отправка формы методом POST в Laravel

Пусть у нас есть контроллер Test и в нем действие form с формой и действие result, на которое эта форма отправляется.

Вот маршруты, соответствующие описанному:

<?php Route::get('test/form', 'TestController@form'); Route::get('test/result', 'TestController@result'); ?>

Вот форма, расположенная в представлении действия form:

<form action="/test/result/"> <input type="text" name="text"> <input type="submit"> </form>

Как вы видите, эта форма отправляется на адрес /test/result/, то есть на действие result.

Так как атрибут method у формы не указан, то эта форма отправляется HTTP методом GET. Можно указать метод и в явном виде, добавив в форму атрибут method:

<form action="/test/result/" method="GET"> <input type="text" name="text"> <input type="submit"> </form>

Давайте теперь будем отправлять форму методом POST. Для этого поменяем значение атрибута method с GET на POST:

<form action="/test/result/" method="POST"> <input type="text" name="text"> <input type="submit"> </form>

Однако, если ограничиться только этим изменением, то отправка формы приведет к ошибке. Суть ошибки будет сводиться к тому, что нашему маршруту разрешено принимать данные только методом GET, но не методом POST.

Дело в том, что в нашем маршруте используется метод get класса Route:

<?php Route::get('test/result', 'TestController@result'); ?>

Данный метод get разрешает отправлять только GET запросы. Чтобы разрешить отправку POST запросов, поменяем метод get на метод post:

<?php Route::post('test/result', 'TestController@result'); ?>

Теперь наш маршрут будет принимать POST запросы (но уже не будет принимать GET).

Попытка отправить форму, однако, все равно приведет к ошибке с текстом "The page has expired due to inactivity.". Данная ошибка уже имеет другую природу, не связанную с маршрутами: просто в форме, отправляемой методом POST необходимо передавать CSRF-токен для защиты от хакерских атак.

CSRF (англ. Сross Site Request Forgery - "межсайтовая подделка запроса") - вид атак на посетителей сайтов, использующий недостатки протокола HTTP.

Для исправления проблемы проблемы в тексте формы нужно написать следующую команду: {{ csrf_field() }}

Сделаем это:

<form action="/test/result/" method="POST"> {{ csrf_field() }} <input type="text" name="text"> <input type="submit"> </form>

Вот теперь наша форма наконец станет отправляться методом POST. Для получения отправленных данных нужно использовать тот же объект Request - он содержит одновременно и данные, отправленные методом GET, и данные, отправленные методом POST.

Сделайте два действия. В представлении первого действия покажите форму, которая будет отправляться на второе действие методом POST. Выведите данные, отправленные через форму, в представлении второго действия.

Получение и проверка метода запроса

Для получения метода HTTP запроса можно использовать метод method:

<?php $method = $request->method(); ?>

Можно также использовать метод isMethod для проверки соответствия HTTP-метода заданной строке:

<?php if ($request->isMethod('post')) { } ?>

Напоминаю вам, что запрос к сайту методом GET - это не только отправка формы этим методом, но и просто запрос любого URL сайта.

Выведите на экран метод HTTP запроса.

Если метод HTTP запроса - GET, то выведите на экран сообщение '!', а если POST, то сообщение '!!'.

Отправка формы и получение в одном действии

Когда мы отправляли форму методом GET, то использовали одно и тоже действие и для показа формы и для получения данных.

При отправке методом POST так просто это не получится, так как при показе формы осуществляется GET запрос к сайту, а при отправке формы - POST.

То есть для решения проблемы нужно сделать на один и тот же адрес два маршрута - один с методом Route::get, а другой - с методом Route::post:

<?php Route::get('test/form', 'TestController@form'); Route::post('test/form', 'TestController@form'); ?>

Для избежания дублирования адресов можно использовать метод match:

<?php Route::match(['get', 'post'], 'test/form', 'TestController@form'); ?>

Используя метод isMethod можно отделить первое обращение к действию для получения формы от второго обращения к действию после отправки формы:

<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller; use Illuminate\Http\Request; class TestController extends Controller { public function form(Request $request) { // Выполнится при первом заходе: if ($request->isMethod('get')) { return view('test.form'); // представление с формой } // Выполнится после отправки формы: if ($request->isMethod('post')) { $text = $request->input('text'); return view('test.result', ['text', $text]); // представление с результатом } } } ?>

Сделайте форму, которая будет спрашивать у пользователя два числа с помощью двух инпутов. После отправки формы методом POST выведите на экран сумму введенных чисел. Пусть и форма, и результат показываются одним действием.