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

React Native对接Django登录功能报错及提交问题解决

问题解决方案

问题1:无http前缀的请求错误与未处理Promise拒绝

原因

  • 请求地址未加http前缀时,React Native的fetch会将其视为相对路径,导致请求无法正确发送到后端接口,触发错误。
  • AuthContext中的错误捕获逻辑错误:.catch(({ e }) => { ... })是错误的解构方式,实际catch接收的是错误对象本身,导致错误未被正确捕获,引发未处理的Promise拒绝。
  • 直接将Error对象赋值给error状态并渲染到React组件中,React无法渲染对象类型,因此出现Objects are not valid as a React child错误。

修复步骤

  1. 保留请求地址的http前缀:React Native中调用外部接口必须使用完整的协议+域名/IP+端口的地址,不能省略http/https。
  2. 修复错误捕获逻辑:修改AuthContext中的onLogin方法,调整加载状态时机和错误捕获方式:
    const onLogin = (email, password) => {
        console.log("HELLO2");
        setIsLoading(true); // 请求开始时立即设置加载状态
        loginRequest(email, password)
            .then((loginUser) => {
                setUser(loginUser);
                setError(null); // 登录成功清空错误状态
            })
            .catch((e) => { // 直接接收错误对象,避免错误解构
                setError(e.message || '登录失败'); // 提取错误信息,避免渲染对象
            })
            .finally(() => { // 无论成功失败,最终关闭加载状态
                setIsLoading(false);
            });
    };
    
  3. 优化loginRequest的错误处理:后端返回的是字段级错误数组,将其转换为可读字符串,确保抛出的Error有有效message:
    export const loginRequest = async (email, password) => {
        console.log("login", email, password); // 打印参数,确认传递值是否正确
        const response = await fetch("http://172.25.80.1:19000/api/user/token/", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify({
                email: email,
                password: password,
            }),
        });
    
        const data = await response.json();
        console.log(data);
    
        if (!response.ok) {
            // 拼接所有后端返回的错误信息
            const errorMessages = Object.values(data).flat().join(' ');
            throw new Error(errorMessages || '登录请求失败');
        }
        return data;
    };
    

问题2:后端返回邮箱无效、密码必填的验证错误

原因

  • 字段名不匹配:Django REST Framework默认的Token认证接口(如api-token-auth/)接受username和password字段,而前端传递的是email字段,后端无法识别导致验证失败。
  • 输入参数为空:点击登录时,email或password的state值可能为空,后端接收到空值触发验证错误。

修复步骤

  1. 对齐前后端字段名:
    • 如果使用DRF默认Token认证,前端将email的值放在username字段传递:
      // 修改loginRequest中的body部分
      body: JSON.stringify({
          username: email, // 把邮箱作为用户名传递
          password: password,
      }),
      
    • 如果后端是自定义Token接口,确保序列化器中配置了email和password字段。
  2. 验证前端输入参数:在onLogin中打印参数,确认点击登录时email和password不为空:
    const onLogin = (email, password) => {
        console.log('登录参数:', email, password); // 检查参数是否有效
        // ... 后续逻辑
    };
    
  3. 后端自定义邮箱登录序列化器(可选):若要让后端直接支持邮箱登录,可自定义序列化器替换默认的AuthTokenSerializer:
    from rest_framework import serializers
    from django.contrib.auth import authenticate
    from django.utils.translation import gettext_lazy as _
    
    class EmailTokenSerializer(serializers.Serializer):
        email = serializers.EmailField()
        password = serializers.CharField(style={'input_type': 'password'})
    
        def validate(self, attrs):
            email = attrs.get('email')
            password = attrs.get('password')
    
            if email and password:
                user = authenticate(request=self.context.get('request'),
                                    username=email, password=password)
                if not user:
                    raise serializers.ValidationError(_('无效的邮箱或密码'))
            else:
                raise serializers.ValidationError(_('必须填写邮箱和密码'))
    
            attrs['user'] = user
            return attrs
    
    然后在urls.py中配置使用该序列化器的视图:
    from rest_framework.authtoken.views import ObtainAuthToken
    from .serializers import EmailTokenSerializer
    from django.urls import path
    
    urlpatterns = [
        path('api/user/token/', ObtainAuthToken.as_view(serializer_class=EmailTokenSerializer), name='token'),
    ]
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 10:53:13