P
P
photosho2016-01-05 15:00:55
Laravel
photosho, 2016-01-05 15:00:55

Why is the POST array empty?

Hello. It is necessary to send an AJAX request in Laravel using the POST method and receive some response from the server. I do this:
1. I create a controller (AjaxController.php) with the following code:

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

2. I create a rule (routes.php):
Route::post('/ajax/request', '[email protected]');

3. I access a specific address using the jQuery "ajax" method:
jQuery.ajax({
  url: location.origin + '/ajax/request',
  async: false,
  type: 'POST',
  data: {'param': 32},
  dataType: 'json',
  success: function(data) {alert(data)},
  error: function() {alert('Ошибка')}
});

As a result, the server returns an error. If you make a GET request with the same parameters (just change all "post" to "get"), then everything works correctly. And here POST-requests does not want to send. Having looked, I found that the POST array, in general, comes to the server empty. What could be the problem?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
P
photosho, 2016-01-05
@photosho

So, the problem was in the missing "X-XSRF-TOKEN" parameter in the request (moreover, that's right, and not "X-CSRF-TOKEN", as one might think). This is one. The second is in the encryption of this parameter, but it was not possible to fully understand it.
With each POST request, this parameter must be passed to the server, so the jQuery code will be like this:

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

Here we get the value of the "csrf-token" parameter from the page's meta tags. And we write them there, for example, in the main view file:
But even if all this is done, the server will still die with a "DecryptException" message. I found information about this issue here . True, in the end I did it in the second way, since in the first one the need to add a parameter to each controller seemed terrible.
That is, I opened the file "app/Http/Middleware/VerifyCsrfToken.php" and added the following code to it:
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));
}

A function, of course, inside a class.
I would like to see your opinion in the comments. The women say that the second option may carry some vulnerabilities, but I am not very strong in these matters yet, so I will be glad for any advice on this topic.

S
Stanislav, 2016-01-05
@mzcoding

one)

<?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', '[email protected]');

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('Ошибка');
  }
});

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question