PHP如何正确接收Redux Toolkit Query提交的$_POST数据
问题根因
PHP端$_POST始终为空,是请求体格式与PHP默认解析规则不匹配导致的:
- 前端在
fetchBaseQuery的prepareHeaders中强制设置了Content-Type: application/json,RTK Query发送POST请求时会直接将传入的参数序列化为JSON字符串传输 - PHP原生
$_POST超全局变量仅会自动解析application/x-www-form-urlencoded、multipart/form-data两种格式的POST请求体,对于application/json格式的原始JSON请求体,不会自动填充到$_POST中,因此读取结果为空。
修复方案
两种方案二选一即可,优先选择方案1,符合现代前后端接口交互的通用规范。
方案1:后端兼容JSON请求体(推荐)
无需修改前端代码,在PHP业务逻辑起始位置添加JSON请求体解析逻辑,手动读取原始请求流解析为数组后合并到$_POST即可,核心修改代码如下:
// 所有业务逻辑前添加,兼容JSON格式POST请求 if (stripos($_SERVER['CONTENT_TYPE'], 'application/json') !== false) { $rawPost = file_get_contents('php://input'); $parsedPost = json_decode($rawPost, true); if (is_array($parsedPost)) { $_POST = array_merge($_POST, $parsedPost); } } // 原有业务逻辑保持不变 header('Access-Control-Allow-Origin: *'); header("Access-Control-Allow-Methods: HEAD, GET, POST, PUT, PATCH, DELETE, OPTIONS"); header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method,Access-Control-Request-Headers, Authorization"); header('Content-Type: application/json'); if ($_SERVER['REQUEST_METHOD'] == "OPTIONS") { header('Access-Control-Allow-Origin: *'); header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method,Access-Control-Request-Headers, Authorization"); header("HTTP/1.1 200 OK"); die(); } $str="HELLO WORLD"; $r=""; for ($i = 0; $i < strlen($str); $i++){ if (rand(0,100)>50) $r .= strtoupper($str[$i]); else $r .= strtolower($str[$i]); } file_put_contents("data".$_POST["id"].".txt",$r); echo json_encode($_POST);
方案2:前端修改为表单格式提交
如果不便修改后端逻辑,可以调整前端请求体格式,让PHP自动解析:
- 删除
prepareHeaders中手动设置Content-Type: application/json的配置,浏览器会自动为表单格式的请求体匹配正确的请求头 - 提交mutation时将普通参数对象转换为
URLSearchParams类型的表单数据
核心修改后的前端代码如下:
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; export const postApi = createApi({ reducerPath: "postApi", baseQuery: fetchBaseQuery({ baseUrl: "https://webcodingcenter.com/shared/" // 移除原有手动设置Content-Type的逻辑 }), endpoints: (builder) => ({ getPost: builder.query({ query: (id) => `get_post.php?id=${id}` // expects a JSON response }), updatePost: builder.mutation({ query: (body) => { // 将普通对象转换为urlencoded格式表单 const formBody = new URLSearchParams(body); return { url: `update_post.php`, method: "POST", body: formBody }; } }) }) }); export const { useGetPostQuery, useUpdatePostMutation } = postApi;
注意:如果后续需要提交文件,将请求体替换为
FormData实例即可,同样无需手动设置Content-Type,浏览器会自动生成带分隔符参数的multipart/form-data请求头,PHP可正常通过$_POST、$_FILES解析数据。
内容的提问来源于stack exchange,提问作者Chong Lip Phang
相关产品推荐
相关产品推荐

