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

React Native对接Laravel上传PDF报422错误,求排查方案

React Native + Laravel PDF上传422错误排查与解决

问题分析

422状态码表示请求参数验证失败,结合你的代码,问题主要集中在前端FormData构造和请求头设置上,以下是具体解决步骤:

解决方法

  1. 修正FormData文件构造
    Expo DocumentPicker返回的完整对象不能直接append到FormData,需要提取uri、name、type字段构造符合表单要求的文件对象:
// 修改pickDocument方法
const pickDocument = async () => {
  try {
    const result = await DocumentPicker.getDocumentAsync({
      type: 'application/pdf',
    });
    if (result.type === 'success') {
      const file = result.assets[0];
      // 构造符合FormData规范的文件对象
      setSelectedFile({
        uri: file.uri,
        name: file.name,
        type: 'application/pdf'
      });
    }
  } catch (error) {
    console.error('Error picking document: ', error);
  }
};
  1. 移除手动设置的Content-Type
    axios会自动为FormData请求生成包含boundary的multipart/form-data请求头,手动设置会丢失boundary参数,导致Laravel无法正确解析表单数据,删除请求中的headers配置:
const response = await axiosConfig.post('/upload-pdf', formData);
  1. 验证规则匹配检查
    确认Laravel验证规则中的字段名pdf_file与前端append的字段名完全一致,同时确保上传文件为PDF格式且大小不超过10MB。

详细错误信息查看位置

  • 前端:在catch块中打印error.response.data,可直接获取Laravel返回的具体验证错误详情:
catch (error) {
  console.error('详细错误信息:', error.response?.data);
}
  • Laravel后端:日志文件位于项目根目录下的storage/logs/laravel.log,里面会记录所有请求的验证错误、异常信息,直接查看即可定位问题。

完整代码

React Native前端代码

import React, { useState, useContext } from 'react';
import { View, Button, Text } from 'react-native';
import * as DocumentPicker from 'expo-document-picker';
import { AuthContext } from '../context/AuthProvider';
import axiosConfig from '../helpers/axiosConfig';

const UploadPDFScreen = () => {
  const [selectedFile, setSelectedFile] = useState(null);
  const { user } = useContext(AuthContext);

  const pickDocument = async () => {
    try {
      const result = await DocumentPicker.getDocumentAsync({
        type: 'application/pdf',
      });
      if (result.type === 'success') {
        const file = result.assets[0];
        setSelectedFile({
          uri: file.uri,
          name: file.name,
          type: 'application/pdf'
        });
      }
    } catch (error) {
      console.error('Error picking document: ', error);
    }
  };

  const uploadFile = async () => {
    if (!selectedFile) {
      console.error('No file selected');
      return;
    }

    try {
      const formData = new FormData();
      formData.append('pdf_file', selectedFile);

      axiosConfig.defaults.headers.common['Authorization'] = 'Bearer ' + user.token;

      const response = await axiosConfig.post('/upload-pdf', formData);

      console.log('Upload success:', response.data);
    } catch (error) {
      console.error('Error uploading file:', error);
      console.error('详细错误信息:', error.response?.data);
    }
  };

  return (
    <View>
      <Button title="Select PDF File" onPress={pickDocument} />
      <Button title="Upload File" onPress={uploadFile} disabled={!selectedFile} />
      {selectedFile && (
        <View>
          <Text>Selected PDF: {selectedFile.name}</Text>
        </View>
      )}
    </View>
  );
};

export default UploadPDFScreen;

Laravel后端代码

<?php

namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;

class FileUploadController extends Controller
{
    /**
     * Handle the upload of a PDF file.
     *
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function uploadPdf(Request $request)
    {
        // Define the validation rules
        $validator = Validator::make($request->all(), [
            'pdf_file' => 'required|file|mimes:pdf|max:10240', // max size 10MB
        ]);

        // Check if the validation fails
        if ($validator->fails()) {
            return response()->json(['error' => $validator->errors()], 422);
        }

        // Retrieve the validated file
        $file = $request->file('pdf_file');

        // Store the file in the specified directory
        $filePath = $file->store('public/pdfs');

        // Return a successful response with the file path
        return response()->json([
            'file_path' => Storage::url($filePath),
            'message' => 'File uploaded successfully',
        ], 201);
    }
}

内容的提问来源于stack exchange,提问作者Ahmed Habeeb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 18:22:03