Django+React Native注册:如何按错误类型分发对应错误动作?
问题原因分析
- 错误响应判断逻辑错误:Django返回的错误是对象结构,前端直接拿
error.response.data和字符串比较必然不成立 - 请求头设置错误:使用FormData时手动设置
Content-Type: application/json,导致后端无法正确解析表单数据 - 成功状态码判断错误:Django返回的创建成功状态是
201 Created,前端判断res.status === 200会忽略成功响应 - 异步代码写法冗余:同时使用
await和.then(),易造成逻辑混乱
修复方案
第一步:优化Django视图(可选,让错误格式更规范)
class CreateUser(APIView): queryset = User.objects.all() def post(self, request): avi_pic = request.data.get('avi_pic') username = request.data.get('username') try: user = User.objects.get(username=username) return Response({'error': 'Username is already taken.'}, status=status.HTTP_400_BAD_REQUEST) except User.DoesNotExist: # create方法自动执行save,无需额外调用 user = User.objects.create(avi_pic=avi_pic, username=username) serializer = UserRegisterSerializer(user) return Response(serializer.data, status=status.HTTP_201_CREATED) except Exception as e: # 捕获具体异常,避免吞掉所有错误 return Response({'error': 'An unexpected error occurred.'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
第二步:修复React Native前端代码
const completeSignUp = dispatch => async data => { const formData = new FormData(); const username = data.user_name; formData.append('avi_pic', { uri: data.avi_pic, type: 'image/jpeg', name: data.avi_pic.split('/').pop(), // 优化文件名,避免用完整URI作为文件名 }); formData.append('username', username.toLowerCase()); try { // 移除手动设置的Content-Type,让axios自动处理FormData的请求头 const res = await axios.post(`${BACKEND_URL}/register/`, formData); // 匹配Django返回的201状态码 if (res.status === 201){ await RNSInfo.setItem('user', 'true', {}); // 异步操作加await确保执行完成 dispatch({ type: 'signin', user: 'true', }); } } catch (error) { if (error.response && error.response.data) { // 匹配Django返回的错误字段结构 if (error.response.data.error === 'Username is already taken.') { dispatch({ type: 'username_error', error: 'This username is already taken. Please choose a different one.', }); } else { dispatch({ type: 'error_1', payload: error.response.data.error || 'Something went wrong. Please try again.', }); } } else { // 处理网络错误等无响应的情况 dispatch({ type: 'error_1', payload: 'Network error. Please check your connection.', }); } } };
关键修复点说明
- 请求头修正:删除手动设置的
Content-Type: application/json,axios会自动为FormData设置正确的multipart/form-data请求头,确保后端能解析文件和表单数据 - 错误判断修正:将
error.response.data === 'xxx'改为error.response.data.error === 'xxx',匹配Django返回的对象结构 - 状态码修正:将成功判断改为
res.status === 201,对应Django的HTTP_201_CREATED - 异步逻辑优化:移除冗余的
.then(),统一用await处理异步操作;RNSInfo.setItem是异步操作,加await确保数据存储完成再分发动作 - 文件名优化:将图片文件名改为URI的最后一段,避免使用完整路径作为文件名
内容的提问来源于stack exchange,提问作者jdez
相关产品推荐
相关产品推荐

