2016-01-31 3 views
2

У меня возникают проблемы с запросом AJAX POST в Laravel 5.2. Я передаю действительный токен CSRF в моем запросе AJAX.Laravel 5.2 Ajax POST TokenMismatchException с действительным токеном CSRF

Открытие и закрытие формы с использованием меток формы Laravel Collective HTML package, который автоматически добавляет скрытый вход _token с токеном CSRF. Вынесено HTML:

<form method="POST" action="http://www.example.com/admin/products/search" accept-charset="UTF-8" id="product-search-form"> 
<input name="_token" type="hidden" value="mOaBxU1sVUsRX1KkuAeVhSDSxj0LKT8DDxl9USQc"> 

<div> 
    <label for="keywords" class="required">Keywords</label> 
    <input id="keywords" placeholder="Enter keywords" name="keywords" type="text"> 
</div> 

<div> 
    <label for="category" class="required">Category</label> 
    <select id="category" name="category"> 
     <option selected="selected" value="">Choose a category...</option> 
     <option value="category-1">Category 1</option> 
     <option value="category-2">Category 2</option> 
     <option value="category-3">Category 3</option> 
    </select> 
</div> 

<div> 
    <button id="search-product-submit" type="submit">Search</button> 
</div> 

</form> 

Использование Fetch API и FormData сделать AJAX запрос:

function $(id) { 
    return document.getElementById(id); 
} 

var searchProductSubmitButton = $("search-product-submit"); 

function fetchStatus(response) { 
    if (response.status >= 200 && response.status < 300) { 
     return Promise.resolve(response); 
    } else { 
     return Promise.reject(new Error(response.statusText)); 
    } 
} 

function fetchJson(response) { 
    return response.json(); 
} 

function searchProducts(evt){ 
    var keywords = $("keywords").value, 
     categorySelect = $("category"), 
     category = categorySelect.options[categorySelect.selectedIndex].value, 
     csrfToken = document.getElementsByTagName("meta")["csrf-token"].getAttribute("content"), 
     productSearchForm = $("product-search-form"), 
     formData = new FormData(productSearchForm); 

    evt.preventDefault(); 

    if(keywords !== "" && category !== ""){ 
     fetch("/admin/products/search", { 
      method: "POST", 
      body: formData, 
      headers: { 
       "X-CSRF-TOKEN": csrfToken 
      } 
     }) 
     .then(fetchStatus) 
     .then(fetchJson) 
     .then(function(products) { 
      console.log("The operation was a complete success"); 
     }).catch(function(error) { 
      console.log("Request failed", error); 
     }); 
    } 
} 
searchProductSubmitButton.addEventListener("click", searchProducts, false); 
searchProductSubmitButton.addEventListener("keypress", searchProducts, false); 

токен и данные формы CSRF находятся в полезной нагрузке запроса:

------WebKitFormBoundaryQFECPn7xpptqi076 
Content-Disposition: form-data; name="_token" 

mOaBxU1sVUsRX1KkuAeVhSDSxj0LKT8DDxl9USQc 
------WebKitFormBoundaryQFECPn7xpptqi076 
Content-Disposition: form-data; name="keywords" 

dsafafa 
------WebKitFormBoundaryQFECPn7xpptqi076 
Content-Disposition: form-data; name="category" 

DVD 
------WebKitFormBoundaryQFECPn7xpptqi076-- 

_token вход в полезная нагрузка запроса и заголовок x-csrf-token совпадают с токеном, видимым в View Source.

Маршрут использует веб-межплатформенное:

Route::group(['prefix' => 'admin', 'middleware' => 'web'], function() { 
    Route::post('products/search', [ // == "admin/products/search" with prefix 
     'as' => 'products.search', 
     'uses' => '[email protected]' 
    ]); 
}); 

Контроллер:

public function search(SearchRequest $request){ 
    Log::info('keywords: ' . $request->keywords); 
    Log::info('category: ' . $request->category); 

    return response()->json([ 
     'keywords' => $request->keywords, 
     'category' => $request->category 
    ], 200); 
} 
+0

Были ли запросы к вашему приложению в получении между маркером и представить его? – Boyd

+0

Нет, я нахожусь в своей локальной среде разработки и открываю сайт только на одной вкладке браузера. – kirkaracha

+0

Вы уверены, что не генерируете его дважды? Один раз для элемента формы и один раз для метатега? – Boyd

ответ

0

У меня были проблемы, иногда слишком и установил ее, отправив POST с _token вместо того, чтобы положить его в заголовках.

Или почему бы вам не сериализовать всю форму?

+0

Я уже отправляю _token с сообщением. Оба показывают правильный токен CSRF. Я могу попробовать сериализовать, но вам не нужно использовать API FormData. – kirkaracha

+0

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

Смежные вопросы