@photosho

Почему массив POST пустой?

Здравствуйте. Необходимо в Laravel отправить AJAX-запрос методом POST и получить от сервера некоторый ответ. Делаю так:

1. Создаю контроллер (AjaxController.php) со следующим кодом:

<?php namespace App\Http\Controllers;
class AjaxController extends Controller {
	public function request() {
		$param = \Request::post('param');
		echo json_encode($param);
	}
}


2. Создаю правило (routes.php):

Route::post('/ajax/request', 'AjaxController@request');


3. Обращаюсь к конкретному адресу при помощи jQuery-метода "ajax":

jQuery.ajax({
	url: location.origin + '/ajax/request',
	async: false,
	type: 'POST',
	data: {'param': 32},
	dataType: 'json',
	success: function(data) {alert(data)},
	error: function() {alert('Ошибка')}
});


В результате сервер возвращает ошибку. Если с теми же параметрами сделать GET-запрос (просто поменять все "post" на "get"), то все работает правильно. А вот POST-запросы отправлять не хочет. Посмотрев - обнаружил, что POST-массив, вообще, приходит на сервер пустым. В чем может быть проблема?
  • Вопрос задан
  • 3373 просмотра
Решения вопроса 1
@photosho Автор вопроса
Итак, проблема была в отсутствующем в запросе параметре "X-XSRF-TOKEN" (причем, именно так, а не "X-CSRF-TOKEN", как можно было подумать). Это одна. Вторая - в шифровании этого параметра, но ее до конца понять не удалось.

С каждым POST-запросом этот параметр должен передаваться на сервер, поэтому, на jQuery будет такой код:

jQuery.ajaxSetup({
    headers: {'X-XSRF-TOKEN': jQuery('meta[name="csrf-token"]').attr('content')}
});


Здесь мы получаем значение параметра "csrf-token" из мета-тегов страницы. А записываем их туда, например, в основном файле представления:

<meta name="csrf-token" content="{{ csrf_token() }}"/>


Но даже если все это сделать, сервер все равно будет умирать с сообщением "DecryptException". Информацию об этой проблеме нашел вот здесь. Правда, в итоге сделал вторым способом, так как в первом необходимость добавлять параметр каждому контроллеру показалась страшной.

То есть, я открыл файл "app/Http/Middleware/VerifyCsrfToken.php" и добавил в него такой код:

use Symfony\Component\Security\Core\Util\StringUtils;
...
protected function tokensMatch($request) {
	$token = $request->session()->token();
	$header = $request->header('X-XSRF-TOKEN');
	return StringUtils::equals($token, $request->input('_token')) ||
		($header && StringUtils::equals($token, $header));
}


Функцию, конечно же, внутрь класса.

Хотелось бы в комментариях увидеть ваше мнение. Бабы говорят, что второй вариант может нести какие-то уязвимости, но я пока не очень силен в этих вопросах, поэтому буду рад любому совету по этой теме.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
mzcoding
@mzcoding
Web-Разработка
1)
<?php namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class AjaxController extends Controller {
  public function request(Request $request) {
  	if($request->ajax()){
  		$param = $request->input('param');
  		echo json_encode($param);
  	}
   }
}

2)
Route::post('ajax/request', 'AjaxController@request');

3)
jQuery.ajax({
  url: location.origin + '/ajax/request',
  async: false,
  type: 'POST',
  data: {'param': '32'},
  dataType: 'json',
  success: function(data) {
  	alert(data);
  },
  error: function() {
  	alert('Ошибка');
  }
});
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы