我如何使用本机发布或放置原始二进制文件

Mon*_*key 6 amazon-s3 react-native fetch-api

我需要将图像文件从react本机应用程序放置到预先配置的s3上传URL中。我看到了一个带有fetch的示例,该示例通过路径将图像上传为二进制文件,但它是作为多部分表单上传进行的。由于s3上传网址只能将其作为主体中的原始二进制文件使用-而不作为多部分的内容类型,因此使用fetch或其他任何其他在本机中运行的库将原始二进制图像作为主体放置成什么语法?

以下代码将其上传为表单数据-这不是我想要的。

          var photo = {
            uri: response.uri,
            name: fileName,
          };
          const body = new FormData();  // how can I do this not as a form?
          body.append('photo', photo);
          const results = await fetch('https://somes3uploadurl.com, {
            method: 'PUT',
            body,
          });
Run Code Online (Sandbox Code Playgroud)

Abd*_*oui 6

事实证明,您可以通过多种方式发送文件,包括base64和作为Buffer

使用react-native-fsbuffer

以base64格式上传可以正常工作,但是图像被损坏。所以我使用缓冲区上传:

export const uploadToAws = async (signedRequest, file) => {
  const base64 = await fs.readFile(file.uri, 'base64')
  const buffer = Buffer.from(base64, 'base64')
  return fetch(signedRequest, {
    method: 'PUT',
    headers: {
    'Content-Type': 'image/jpeg; charset=utf-8',
    'x-amz-acl': 'public-read',
   },
    body: buffer,
  })
}
Run Code Online (Sandbox Code Playgroud)

请注意,在服务器上,您需要确保设置了正确的Content-Type:{ ContentType: "image/jpeg; charset=utf-8", 'x-amz-acl': 'public-read' }似乎fetch将字符集添加到Content-Type。


wha*_*are 5

您还可以使用下一个解决方案:

  /**
   * @param {{contentType: string, uploadUrl: string}} resourceData for upload your image
   * @param {string} file path to file in filesystem 
   * @returns {boolean} true if data uploaded
   */
  async uploadImage(resourceData, file) {
    return new Promise((resolver, rejecter) => {
      const xhr = new XMLHttpRequest();

      xhr.onload = () => {
        if (xhr.status < 400) {
          resolver(true)
        } else {
          const error = new Error(xhr.response);
          rejecter(error)
        }
      };
      xhr.onerror = (error) => {
        rejecter(error)
      };

      xhr.open('PUT', resourceData.uploadUrl);
      xhr.setRequestHeader('Content-Type', resourceData.contentType);
      xhr.send({ uri: file });
    })
  }
Run Code Online (Sandbox Code Playgroud)

并从您的代码中调用此函数,如下所示:

  let isSuccess = await uploadImage({
    contentType: "image/jpeg",
    uploadUrl: "http://my.super.web.amazon.service..."
  }, "file:///path-to-file-in-filesystem.jpeg")
Run Code Online (Sandbox Code Playgroud)

来源: https: //github.com/react-native-community/react-native-image-picker/issues/61#issuecomment-297865475

  • 这绝对需要成为新的公认答案。将文件读入 base64 并发布可能会占用大量内存。此方法不会导致此类问题,因为它直接从文件系统读取。 (2认同)