You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RTK Query突变请求Token不一致致Laravel返回419错误的解决方法

Laravel + RTK Query Mutation 419错误解决及原因分析

问题原因

  1. Laravel默认对GET请求豁免CSRF验证,所以你的所有查询接口(均为GET)即便没有携带正确的CSRF令牌,也能正常返回数据。
  2. 你的mutation使用的是PATCH请求,属于Laravel要求CSRF验证的请求类型,必须携带有效令牌。当前问题的核心是mutation请求使用的令牌无效/与当前会话不匹配,而查询请求因为不需要验证,所以没暴露这个问题。

解决方法

统一为所有请求(包括查询和mutation)配置正确的CSRF令牌请求头,修改你的RTK Query代码如下:

第一步:确保Laravel模板包含CSRF Meta标签

在你的Laravel blade模板头部添加:

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

第二步:修改RTK Query的fetchBaseQuery配置

添加prepareHeaders函数,统一注入CSRF令牌到请求头:

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

// 从meta标签获取CSRF令牌
const getCsrfToken = () => {
  const metaTag = document.querySelector('meta[name="csrf-token"]');
  return metaTag ? metaTag.content : '';
};

// (可选)若依赖Cookie传递令牌,可改用此方式读取
// const getCsrfToken = () => {
//   const cookieMatch = document.cookie.match('(^|;)\\s*XSRF-TOKEN\\s*=\\s*([^;]+)');
//   return cookieMatch ? decodeURIComponent(cookieMatch.pop()) : '';
// };

export const apiSlice = createApi({
    baseQuery: fetchBaseQuery({
        baseUrl: 'http://localhost:8000',
        // 若需要携带Cookie(比如会话认证),开启此项
        credentials: 'include',
        prepareHeaders: (headers) => {
            const csrfToken = getCsrfToken();
            if (csrfToken) {
                // Laravel通过X-XSRF-TOKEN头验证CSRF令牌
                headers.set('X-XSRF-TOKEN', csrfToken);
            }
            return headers;
        },
    }),
    endpoints: builder => ({
        getTransactions: builder.query({
            query: () => 'api/transactions'
        }),
        deleteTransaction: builder.mutation({
            query: transactionId => ({
                url: `api/transactions/${transactionId}/delete`,
                method: 'PATCH',
            }),
        }),
        getAccounts: builder.query({
            query: () => 'api/accounts'
        }),
        getPayees: builder.query({
            query: () => 'api/payees'
        }),
        getSpents: builder.query({
            query: () => 'api/spents'
        }),
        getInvestments: builder.query({
            query: () => 'api/investments'
        }),
    })
})

// 其余导出代码保持不变
export const { useGetTransactionsQuery, useDeleteTransactionMutation, 
    useGetAccountsQuery, useGetPayeesQuery, useGetSpentsQuery, useGetInvestmentsQuery } = apiSlice;

export const useGetAccountQuery = (accountId) => {
    return useGetAccountsQuery(undefined, {select: (accounts) => accounts[accountId]});
};

export const useGetPayeeQuery = (payeeId) => {
    return useGetPayeesQuery(undefined, {select: (payees) => payees[payeeId]});
};

export const useGetSpentQuery = (spentId) => {
    return useGetSpentsQuery(undefined, {select: (spents) => spents[spentId]});
};

export const useGetInvestmentQuery = (investmentId) => {
    return useGetInvestmentsQuery(undefined, {select: (investments) => investments[investmentId]});
};

补充说明

  • 之前查询请求中显示的“Token”其实没有被Laravel验证,所以能成功;而mutation请求必须通过CSRF验证,使用无效令牌就会触发419错误。
  • 通过prepareHeaders统一配置后,所有请求都会携带同一个有效的CSRF令牌,mutation请求就能正常通过验证了。

内容的提问来源于stack exchange,提问作者maganthro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 14:06:12