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

React Native登录接口数据未发送,返回参数验证错误

移动端登录请求数据未发送,Web/Postman正常,React Native返回验证错误

问题现象

  • 移动端登录时,接口返回错误:{"message":"email must be an email, password must be a string"}
  • Web端和Postman测试登录接口完全正常
  • 错误日志显示Axios发送的请求体为空对象:"data": "{}"

Axios集成代码

export const SignInBody = () => {
  const [passwordVisible, setPasswordVisible] = useState(true);
  const navigation = useNavigation();
  const [login, setLogin] = useState('');
  const [password, setPassword] = useState('');
  const handleLogin = () => {
    axios
      .post(`${PROTOCOL}${REACT_APP_BACK_URL}/login`, {
        email: login,
        password: password,
      })
      .then(function (response) {
        AsyncStorage.setItem('userId', response.data.data.id)?.toString();
        navigation.navigate('Root', { screen: 'one' });
      })
      .catch(function (error) {
        console.log(error.response);
        errorAlert({
          title: 'Atenção',
          msg: 'Email ou senha incorretos',
          btn: 'Ok',
        });
      });
  };

完整错误信息

Object {
  "config": Object {
    "adapter": [Function xhrAdapter],
    "data": "{}",
    "env": Object {
      "FormData": null,
    },
    "headers": Object {
      "Accept": "application/json, text/plain, */*",
      "Content-Type": "application/json",
    },
    "maxBodyLength": -1,
    "maxContentLength": -1,
    "method": "post",
    "timeout": 0,
    "transformRequest": Array [
      [Function transformRequest],
    ],
    "transformResponse": Array [
      [Function transformResponse],
    ],
    "transitional": Object {
      "clarifyTimeoutError": false,
      "forcedJSONParsing": true,
      "silentJSONParsing": true,
    },
    "url": "https://mybackurl",
    "validateStatus": [Function validateStatus],
    "xsrfCookieName": "XSRF-TOKEN",
    "xsrfHeaderName": "X-XSRF-TOKEN",
  },
  "data": Object {
    "message": "email must be an email, password must be a string",
  },
  "headers": Object {
    "access-control-allow-credentials": "true",
    "access-control-allow-origin": "*",
    "connection": "keep-alive",
    "content-length": "63",
    "content-security-policy": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests",
    "content-type": "application/json; charset=utf-8",
    "date": "Fri, 15 Jul 2022 03:59:44 GMT",
    "etag": "W/\"3f-ALOE7r8MX9pcEta7jauOf258lOM\"",
    "expect-ct": "max-age=0",
    "referrer-policy": "no-referrer",
    "server": "Cowboy",
    "strict-transport-security": "max-age=15552000; includeSubDomains",
    "vary": "Accept-Encoding",
    "via": "1.1 vegur",
    "x-content-type-options": "nosniff",
    "x-dns-prefetch-control": "off",
    "x-download-options": "noopen",
    "x-frame-options": "SAMEORIGIN",
    "x-permitted-cross-domain-policies": "none",
    "x-xss-protection": "0",
  },
  "request": XMLHttpRequest {
    "DONE": 4,
    "HEADERS_RECEIVED": 2,
    "LOADING": 3,
    "OPENED": 1,
    "UNSENT": 0,
    "_aborted": false,
    "_cachedResponse": undefined,
    "_hasError": false,
    "_headers": Object {
      "accept": "application/json, text/plain, */*",
      "content-type": "application/json",
    },
    "_incrementalEvents": false,
    "_lowerCaseResponseHeaders": Object {
      "access-control-allow-credentials": "true",
      "access-control-allow-origin": "*",
      "connection": "keep-alive",
      "content-length": "63",
      "content-security-policy": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests",
      "content-type": "application/json; charset=utf-8",
      "date": "Fri, 15 Jul 2022 03:59:44 GMT",
      "etag": "W/\"3f-ALOE7r8MX9pcEta7jauOf258lOM\"",
      "expect-ct": "max-age=0",
      "referrer-policy": "no-referrer",
      "server": "Cowboy",
      "strict-transport-security": "max-age=15552000; includeSubDomains",
      "vary": "Accept-Encoding",
      "via": "1.1 vegur",
      "x-content-type-options": "nosniff",
      "x-dns-prefetch-control": "off",
      "x-download-options": "noopen",
      "x-frame-options": "SAMEORIGIN",
      "x-permitted-cross-domain-policies": "none",
      "x-xss-protection": "0",
    },
    "_method": "POST",
    "_perfKey": "network_XMLHttpRequest_https://mybackurl",
    "_performanceLogger": PerformanceLogger {
      "_closed": false,
      "_extras": Object {},
      "_pointExtras": Object {},
      "_points": Object {
        "initializeCore_end": 1657857539044,
        "initializeCore_start": 1657857538868,
      },
      "_timespans": Object {
        "network_XMLHttpRequest_http://192.168.15.7:19000/logs": Object {
          "endExtras": undefined,
          "endTime": 1657857540601,
          "startExtras": undefined,
          "startTime": 1657857540513,
          "totalTime": 88,
        },
        "network_XMLHttpRequest_http://192.168.15.7:19000/symbolicate": Object {
          "endExtras": undefined,
          "endTime": 1657857540548,
          "startExtras": undefined,
          "startTime": 1657857540120,
          "totalTime": 428,
        },
        "network_XMLHttpRequest_https://mybackurl": Object {
          "endExtras": undefined,
          "endTime": 1657857583334,
          "startExtras": undefined,
          "startTime": 1657857558247,
          "totalTime": 25087,
        },
      },
    },
    "_requestId": null,
    "_response": "{\"message\":\"email must be an email, password must be a string\"}",
    "_responseType": "",
    "_sent": true,
    "_subscriptions": Array [],
    "_timedOut": false,
    "_trackingName": "unknown",
    "_url": "MYBACKURL",
    "readyState": 4,
    "responseHeaders": Object {
      "Access-Control-Allow-Credentials": "true",
      "Access-Control-Allow-Origin": "*",
      "Connection": "keep-alive",
      "Content-Length": "63",
      "Content-Security-Policy": "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests",
      "Content-Type": "application/json; charset=utf-8",
      "Date": "Fri, 15 Jul 2022 03:59:44 GMT",
      "Etag": "W/\"3f-ALOE7r8MX9pcEta7jauOf258lOM\"",
      "Expect-Ct": "max-age=0",
      "Referrer-Policy": "no-referrer",
      "Server": "Cowboy",
      "Strict-Transport-Security": "max-age=15552000; includeSubDomains",
      "Vary": "Accept-Encoding",
      "Via": "1.1 vegur",
      "X-Content-Type-Options": "nosniff",
      "X-Dns-Prefetch-Control": "off",
      "X-Download-Options": "noopen",
      "X-Frame-Options": "SAMEORIGIN",
      "X-Permitted-Cross-Domain-Policies": "none",
      "X-Xss-Protection": "0",
    },
    "responseURL": "MYBACKURL",
    "status": 400,
    "timeout": 0,
    "upload": XMLHttpRequestEventTarget {},
    "withCredentials": true,
  },
  "status": 400,
  "statusText": undefined,
}

排查与解决方案

从"data": "{}"可以确定,请求体未正确携带email和password参数,导致后端验证失败,可按以下步骤解决:

1. 检查输入框状态绑定

确保输入框的value和onChangeText正确绑定到对应状态:

// 示例绑定代码
<TextInput
  value={login}
  onChangeText={setLogin}
  placeholder="邮箱"
/>
<TextInput
  value={password}
  onChangeText={setPassword}
  placeholder="密码"
  secureTextEntry={passwordVisible}
/>

若绑定错误,login和password会一直为空字符串,引发序列化异常。

2. 手动序列化请求体

部分React Native环境中Axios默认序列化失效,可手动转换为JSON字符串:

axios.post(`${PROTOCOL}${REACT_APP_BACK_URL}/login`, JSON.stringify({
  email: login,
  password: password,
}), {
  headers: {
    'Content-Type': 'application/json'
  }
})

3. 检查Axios配置与版本

  • 升级Axios到最新稳定版,规避版本兼容性问题
  • 排查全局拦截器是否修改了请求体,避免出现清空数据的逻辑:
    // 错误示例:拦截器清空请求体
    axios.interceptors.request.use(config => {
      config.data = {};
      return config;
    });
    

4. 调试状态值

在handleLogin中打印状态,确认参数是否正确:

const handleLogin = () => {
  console.log('login:', login, 'password:', password);
  axios.post(...)
}

若打印为空,说明输入框绑定有问题;若有值但请求体为空,需排查Axios序列化逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 19:48:06