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

React Native Expo中POST请求失效,GET请求正常的问题排查

问题:POST请求服务器无法接收数据,GET请求正常

我尝试用POST方法实现登录功能,但服务器接收不到请求中的数据。Postman测试时数据能成功发送,先后试过Axios和Fetch API两种方式都无效,但GET请求可以正常工作。

相关代码与信息

请求头配置代码

import axios from 'axios';
import React from 'react';
import { appPackageName, ApiKey, ApiServer } from '@/constants';
import { MyObject } from '@/interface';
import { Platform } from 'react-native';

const headers: MyObject = {
  'Content-Type': 'application/json',
};

if (Platform.OS !== 'web') {
  headers['APP_PACKAGE_NAME'] = appPackageName;
}

Axios请求代码

export async function postData(relativeUrl: string, requestData: MyObject): Promise<MyObject> {
  try {
    headers['Authorization'] = `Bearer ${ApiKey}`;

    console.log({ ...requestData });

    const response = await axios.post(
      `${ApiServer}/${relativeUrl}`,
      { ...requestData }, // 试过JSON.stringify(requestData)、不展开、不序列化的情况都不行
      {
        headers: headers,
        withCredentials: true,
      }
    );

    return response.data;
  } catch (error) {
    console.error('Error fetching data:', error);
    throw new Error('Failed to fetch data');
  }
}

Fetch请求代码

export async function postData(relativeUrl: string, requestData: MyObject): Promise<MyObject> {
  try {
    headers['Authorization'] = `Bearer ${ApiKey}`;

    console.log({ ...requestData });

    const response = await fetch(`${ApiServer}/${relativeUrl}`, {
      method: 'POST',
      headers: headers,
      body: JSON.stringify(requestData),
    });

    console.log(response);

    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Error fetching data:', error);
    throw new Error('Failed to fetch data');
  }
}

GET请求代码

export async function getData(relativeUrl: string, requestData: MyObject): Promise<MyObject> {
  try {
    const response = await axios.get(
      `${ApiServer}/${relativeUrl}`,
      {
        headers: headers,
        params: requestData,
      }
    );
    console.log(response.data);

    return response.data;
  } catch (error) {
    console.error('Error fetching data:', error);
    throw new Error('Failed to fetch data');
  }
}

浏览器请求头

POST /public/auth/login HTTP/1.1
Host: localhost:9016
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br, zstd
Content-Type: application/json
Authorization: Bearer TOKEN_CODE
Content-Length: 97
Origin: http://localhost:8081
Connection: keep-alive
Referer: http://localhost:8081/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Priority: u=0

Postman请求头

Cookie: PHPSESSID=vcug376r85rus7fj3aep0pivmm
Cache-Control: no-cache
Postman-Token: <calculated when request is sent>
Content-Type: multipart/form-data; boundary=<calculated when request is sent>
Content-Length: <calculated when request is sent>
Host: <calculated when request is sent>
User-Agent: PostmanRuntime/7.39.1
Accept: */*
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Authorization: Bearer TOKEN_CODE
Content-Type: application/json

PHP CORS校验代码

/**
 * Set up headers that handle API requests
 */
require_once $_SERVER['DOCUMENT_ROOT'].'/src/env-var.php';

$headers = getallheaders();

// Get the request's Origin header
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';

// Handle preflight requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
    header("Access-Control-Allow-Headers: Authorization, Content-Type, HTTP_X_APP_PACKAGE_NAME");

    if (isset($headers['Authorization']) || isset($headers['Credentials'])) {
        header('Access-Control-Allow-Credentials: true');
    }

    header('Access-Control-Max-Age: 86400'); // Cache for 1 day
    header('Content-Type: application/json');
    exit(0);
}

// Set general CORS headers
header('Content-Type: application/json');

if(preg_match('/development/',ENV)){
    header("Access-Control-Allow-Origin: *");
} 
else if (isset($_SERVER['HTTP_X_APP_PACKAGE_NAME']) && in_array($_SERVER['APP_PACKAGE_NAME'], $allowedApps))
    header("Access-Control-Allow-Origin: *");
elseif (isset($_SERVER['HTTP_ORIGIN']) && in_array($origin, $allowedOrigins))
    header("Access-Control-Allow-Origin: $origin");
else {
    http_response_code(401);
    echo json_encode(['error' => 'Unauthorized Access']);
    exit;
}

// Allow credentials if the request includes Authorization or Credentials header
if (isset($headers['Authorization']) || isset($headers['Credentials'])) {
        header('Access-Control-Allow-Credentials: true');
}

// Allow specified methods
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");

// Allow specific headers
header("Access-Control-Allow-Headers: Authorization, Content-Type, X-Custom-Header");

// Cache for 1 day
header('Access-Control-Max-Age: 86400');

解决方案

1. 修复服务器端JSON格式数据的接收逻辑

前端发送的是application/json格式请求体,但PHP默认仅会解析application/x-www-form-urlencoded或multipart/form-data格式的数据到$_POST数组。如果服务器端仍用$_POST获取数据,自然拿不到JSON内容。

修改服务器端获取POST数据的代码:

// 替换原有的POST数据获取逻辑
$postData = json_decode(file_get_contents('php://input'), true);
// 之后用$postData访问字段,比如$postData['username']

2. 统一请求格式(可选)

Postman请求头同时存在两个Content-Type,实际测试时可能发送的是form-data格式,因此服务器用$_POST能拿到数据。如果要改为前端发送form-data,可调整Axios代码:

import FormData from 'form-data'; // React Native需额外安装form-data包

export async function postData(relativeUrl: string, requestData: MyObject): Promise<MyObject> {
  try {
    headers['Authorization'] = `Bearer ${ApiKey}`;
    delete headers['Content-Type']; // 让Axios自动生成form-data的Content-Type和boundary

    const formData = new FormData();
    Object.keys(requestData).forEach(key => {
      formData.append(key, requestData[key]);
    });

    const response = await axios.post(
      `${ApiServer}/${relativeUrl}`,
      formData,
      {
        headers: headers,
        withCredentials: true,
      }
    );

    return response.data;
  } catch (error) {
    console.error('Error fetching data:', error);
    throw new Error('Failed to fetch data');
  }
}

3. 修正PHP CORS代码的变量错误

原CORS代码中存在变量名错误:

// 原错误代码
else if (isset($_SERVER['HTTP_X_APP_PACKAGE_NAME']) && in_array($_SERVER['APP_PACKAGE_NAME'], $allowedApps))

自定义请求头在PHP的$_SERVER中会被添加HTTP_前缀并转为大写,因此$_SERVER['APP_PACKAGE_NAME']应改为$_SERVER['HTTP_APP_PACKAGE_NAME'],修改后:

else if (isset($_SERVER['HTTP_APP_PACKAGE_NAME']) && in_array($_SERVER['HTTP_APP_PACKAGE_NAME'], $allowedApps))

另外,OPTIONS请求中允许的头是HTTP_X_APP_PACKAGE_NAME,但前端发送的是APP_PACKAGE_NAME,需统一两者:要么前端改为发送X-APP-PACKAGE-NAME,要么OPTIONS中的允许头改为APP_PACKAGE_NAME,避免预请求失败。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:15:54