【问题标题】:Form data of image uploaded as string '[object Object]' when using Expo使用Expo时以字符串'[object Object]'形式上传的图像数据
【发布时间】:2021-01-06 02:30:00
【问题描述】:

我正在尝试上传使用 Expo 的 ImagePicker 检索到的图像。这是我的 React Native 组件:

import * as ImagePicker from "expo-image-picker";

const Foo = () => {
  const [photoUri, setPhotoUri] = useState("");

  const choosePhoto = async () => {
    const result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      quality: 1,
    });

    setPhotoUri(result.cancelled ? "" : result.uri);
  };

  const uploadPhoto = async () => {
    if (photoUri == "") {
      return;
    }

    const formData = new FormData();

    formData.append("photo", {
      uri: photoUri,
      name: "test",
      type: "image/jpeg",
    });

    return await fetch(Constants.manifest.extra.UPLOAD_IMAGE_URI, {
      method: "POST",
      body: formData,
      headers: {
        // No header otherwise multer will complain about missing boundary 
        // "content-type": "multipart/form-data",
      },
    });
  };

  return (
    <View>
      <TouchableOpacity onPress={choosePhoto}>
         <Text>Choose Photo</Text>
        <TouchableOpacity onPress={uploadPhoto}>
          <Text>Confirm Image</Text>
        </TouchableOpacity>
      </TouchableOpacity>
  );
};

这是我的 Express 后端:

import * as express from "express";
import * as multer from "multer";

const app = express();

const fileUpload = multer();

app.post(
  "/profile_image/upload",
  fileUpload.single("photo"),
  async (req, _res, _next) => {
    console.log(req.body);
    console.log(req.body.photo);
    console.log(req.file);
  }
);

  app.listen(
    {
      port: 8000,
    },
    () => {
      console.log("Started server!");
    }
  );

当我在 Web 版本中测试它并检查我的 Chrome 控制台时,它显示请求是在 photo 字段是字符串 '[object Object]' 的地方发出的。

同样,我的 Express 端点将字段解析为字符串:

[Object: null prototype] { photo: '[object Object]' }
[object Object]
undefined

另外,另一个奇怪的事情是ImagePicker 返回的photoUri,至少在 Web 应用程序中,默认为 base64 编码版本,而不是实际的文件路径。不确定这是不是故意的:

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD//gA8Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcgSlBFRyB2NjIpLCBxdWFsaXR5ID0gMTAwCv/bAEMAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA...

【问题讨论】:

  • 再次尝试使用multipart/form-data 标头并尝试访问索引为0 req.body.photo[0]的文件

标签: react-native expo multer


【解决方案1】:

请注意,当 uri 不是 base64 时(例如,在 Android/iOS 上),需要带有 uri, type, name 键的字段对象,但在 web 上使用 ImagePicker 需要以下内容,因为它返回一个 @ 987654325@编码。

选项 1:base64 字段

所以我意识到,由于我正在上传图像的 base64 编码,我不需要将 photo 字段包装在字典中,而是可以这样做:

formData.append("photo", photoUri);

此外,由于photoUri 为 O(1MB),我需要将multer 的 fieldSize 限制增加到合理的值(本例中为 5MB):

const fileUpload = multer({
  limits: { fieldSize: 5 * 1024 * 1024 * 1024 },
});

随后我能够在req.body.photo 中检索到图像的base64 编码。

选项 2:blob 编码

另一个选项是convert the base64 encoding to a Blob,因此它可以与 FormData 一起使用。

formData.append("photo", dataURItoBlob(photoUri));

然后 multer 将能够将上述内容解析为文件,而无需任何限制覆盖:

app.post(
  "/profile_image/upload",
  fileUpload.single("photo"),
  async (req, _res) => {
    console.log("file", req.file);
  }
);
file {
  fieldname: 'photo',
  originalname: 'blob',
  encoding: '7bit',
  mimetype: 'image/jpeg',
  buffer: <Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 00 01 00 00 ff fe 00 3c 43 52 45 41 54 4f 52 3a 20 67 64 2d 6a 70 65 67 20 76 31 2e 30 20 28 75 73 69 ... 2332888 more bytes>,
  size: 2332938
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    • 2021-11-27
    相关资源
    最近更新 更多