【问题标题】:Laravel 5.2 Ajax POST TokenMismatchException with Valid CSRF Token带有有效 CSRF 令牌的 Laravel 5.2 Ajax POST TokenMismatchException
【发布时间】:2016-05-08 16:02:53
【问题描述】:

我在 Laravel 5.2 中遇到了 AJAX POST 请求的问题。我在我的 AJAX 请求中传递了一个有效的 CSRF 令牌。

使用Laravel Collective HTML package 表单标签打开和关闭表单,它会自动添加带有 CSRF 令牌的隐藏 _token 输入。呈现的 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 标头与查看源代码中看到的令牌相同。

Route 正在使用 Web 中间件:

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

控制器:

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);
}

【问题讨论】:

  • 在收到令牌和提交令牌之间是否对您的应用程序有任何请求?
  • 不,我在本地开发环境中,只在一个浏览器选项卡中打开网站。
  • 你确定你没有生成两次吗?一次用于表单元素,一次用于元标记?
  • 元标签和隐藏表单域是一样的。

标签: javascript ajax forms laravel


【解决方案1】:

我有时也遇到这些问题,并通过发送带有_token 的 POST 来解决它,而不是将其放在标题中。

或者你为什么不序列化整个表单?

【讨论】:

  • 我已经在发送 _token 和帖子。两者都显示正确的 CSRF 令牌。我可以尝试序列化,但您不需要使用 FormData API。
  • 好吧,我能想象到的唯一错误是元标记中的标记与表单中的标记不同。尝试发送不带标题的表单
【解决方案2】:

我开始执行 POST 请求,并且正在执行带有 URL 参数的 GET 请求: https://laracasts.com/discuss/channels/laravel/laravel-52-ajax-post-tokenmismatchexception-with-valid-csrf-token/replies/135330

【讨论】:

    猜你喜欢
    • 2017-07-22
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    • 2019-06-29
    • 2017-08-23
    • 1970-01-01
    • 2016-06-17
    相关资源
    最近更新 更多