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

React Native使用fetch发送FormData至Node API失败求助

React Native Expo: Fixing Network Request Failures When Uploading Images to Node API

Hey there, I’ve run into this exact issue before with Expo 35 and React Native 0.59 on Android—FormData handling for file uploads was super finicky back then. Let’s break down what was going wrong and the solutions that work, including the base64 approach you landed on.

Root Cause

The core problem here is that older Expo/React Native versions had inconsistent handling of FormData with file URIs, especially on Android. When you appended the image object directly to FormData, the fetch implementation couldn’t properly parse the file:// URI into a readable stream for the request, leading to the network failure. Even when sending plain string FormData, auto-generated (or manual) content-type headers didn’t set correctly, resulting in an empty body on the server side.


Solution 1: Base64 Encoding (Your Working Fix)

This is a reliable workaround for older Expo versions since it avoids FormData’s file handling entirely. Here’s the end-to-end implementation:

React Native/Expo Side

  1. Modify your image picker to retrieve the base64 string:
import * as ImagePicker from 'expo-image-picker';

const pickImage = async () => {
  let result = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: ImagePicker.MediaTypeOptions.Images,
    allowsEditing: true,
    quality: 0.8,
    base64: true, // Enable base64 encoding for the image
  });

  if (!result.cancelled) {
    const filename = result.uri.split('/').pop();
    await uploadImageAsBase64(result.base64, filename);
  }
};
  1. Send the base64 string and metadata via a JSON request:
const uploadImageAsBase64 = async (base64Image, filename) => {
  try {
    const response = await fetch(`${serverIp}/manageFiles/almacenImagenes`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        fromApp: "true",
        userId: "testID123",
        imageBase64: base64Image,
        filename: filename
      })
    });
    const resData = await response.json();
    console.log("Upload successful:", resData);
  } catch (err) {
    console.log("Upload error:", err);
  }
};

Node.js Server Side

Decode the base64 string and save it as a file:

const fs = require('fs');
const path = require('path');

app.post('/manageFiles/almacenImagenes', async (req, res) => {
  try {
    const { imageBase64, filename, userId } = req.body;
    // Strip the optional data URI prefix added by Expo
    const base64Data = imageBase64.replace(/^data:image\/jpeg;base64,/, '');
    const uploadPath = path.join(__dirname, 'uploads', `${userId}_${filename}`);
    
    fs.writeFileSync(uploadPath, base64Data, 'base64');
    res.status(200).json({ success: true, message: "Image saved successfully" });
  } catch (err) {
    res.status(500).json({ success: false, error: err.message });
  }
});

Solution 2: Fixing FormData for Older Expo Versions

If you prefer to stick with FormData, these tweaks might resolve the network error:

  • Skip manual Content-Type headers: When using FormData, fetch automatically generates the correct multipart/form-data header with a boundary value. Manually setting this header breaks the request, as the boundary won’t match the body.
  • Adjust the image URI for Android: Use Expo’s FileSystem module to convert the file:// URI to a content:// URI, which older React Native versions handle better:
import * as FileSystem from 'expo-file-system';

// Resolve the correct content URI
const contentUri = await FileSystem.getContentUriAsync(image.uri);

let formData = new FormData();
formData.append("imageFile", { 
  uri: contentUri, 
  type: "image/jpeg", 
  name: filename 
});
// Append metadata as individual fields (not objects!)
formData.append("fromApp", "true");
formData.append("userId", "testID123");

Important: Never append objects directly to FormData in older Expo versions—each key-value pair needs to be added separately.

  • Validate server CORS settings: Ensure your Node server accepts multipart/form-data requests and has proper CORS configuration. Using the cors middleware:
const cors = require('cors');
// Allow your Expo app's origin in production (use "*" for testing only)
app.use(cors({ origin: '*', credentials: true }));

Final Notes

For Expo 35 specifically, the base64 method is the most stable choice because it bypasses the FormData bugs that plagued that version. If you ever upgrade to Expo v40+, FormData file uploads work much more reliably out of the box.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:50:19