0

我已经尝试过,但似乎无法使用 UploadCare 在我的 ReactNative Expo 应用程序中上传大文件。

小于 100mb 的较小文件我使用效果很好的直接上传 API。对于大于 100mb 的文件,您需要调用多种方法来上传文件。

  1. 调用多部分开始端点
  2. 将各个部分 (5mb) 上传到分配的 s3 URL
  3. 调用多部分完成

https://uploadcare.com/docs/upload-api/request-based/

这是我尝试过的,目前正在得到:

"content": "File size mismatch. Not all parts uploaded?",
"status_code": 400,

下面是我用来在 ReactNative 中上传文件的代码

const getChunk = (file, index, filesize, chunkSize) => {
  const start = chunkSize * index
  const end = Math.min(start + chunkSize, filesize)

  return file.slice(start, end)
}
const resp = await fetch(image.uri);
const blob = await resp.blob();
const uriParts = image.uri.split('.');
const ext = uriParts[uriParts.length - 1];
const filename = `file.${ext}`;

if (blob.size > 99000000) {
  multipartUpload(blob, filename);
} else {
  directUpload(image, filename);
}
const multipartUpload = async(blob, filename) => {
  try {
    const { uuid, parts } = await multipartStart(blob, filename);
    uploadParts(blob, parts, uuid);    
  } catch (error) {
    console.log(`Error - ${error}`)
  }  
}
const multipartStart = async(blob, filename) => {

  const body = new FormData
  body.append("UPLOADCARE_PUB_KEY", "XXX")
  body.append("filename", filename)
  body.append("size", blob.data.size)
  body.append("content_type", blob.type)
  body.append("UPLOADCARE_STORE", "auto")

  const response = await fetch("https://upload.uploadcare.com/multipart/start/?jsonerrors=1", {
    method: "POST",
    body,
    headers: {
      "Content-Type": "multipart/form-data"
    }
  })

  return response.json();
};
const uploadParts = async(blob, parts, uuid) => {
  const CHUNK_SIZE = 5 * 1024 * 1024;
  const chunks = [];
  for (let i = 0; i < parts.length; i++) {
    chunks.push(getChunk(blob, i, blob.data.size, CHUNK_SIZE));
  }
  console.log(chunks);
  let completed = 0;
  for (let i = 0; i < parts.length; i++) {
    let endpoint = parts[i];
    axios(endpoint, {
      method: 'PUT',
      headers: {
        'Content-Type': blob.type
      },
      data: chunks[i]
    })
    .then(res => {
      if (res.status == 200) {
        completed++;
      }
      console.log('Parts uploaded: ', completed);
      if (completed == parts.length) {
        multipartComplete(uuid);
      }
    })
    .catch(function (error) {
      console.log(error);
    });
  }
};
const multipartComplete = async(uuid) => {

  const body = new FormData
  body.append("UPLOADCARE_PUB_KEY", "XXX")
  body.append("uuid", uuid)

  const response = await fetch("https://upload.uploadcare.com/multipart/complete/?jsonerrors=1", {
    method: "POST",
    body,
    headers: {
      "Content-Type": "multipart/form-data"
    }
  })

  const result = await response.json();
  console.log(result);
};
 Expo CLI 4.1.4 environment info:
    System:
      OS: macOS 10.15.7
      Shell: 5.7.1 - /bin/zsh
    Binaries:
      Node: 12.16.3 - /usr/local/bin/node
      Yarn: 1.22.4 - /usr/local/bin/yarn
      npm: 6.14.4 - /usr/local/bin/npm
    SDKs:
      iOS SDK:
        Platforms: iOS 14.4, DriverKit 20.2, macOS 11.1, tvOS 14.3, watchOS 7.2
    IDEs:
      Android Studio: 3.6 AI-192.7142.36.36.6392135
      Xcode: 12.4/12D4e - /usr/bin/xcodebuild
    npmPackages:
      expo: ^40.0.1 => 40.0.1 
      react: 16.13.1 => 16.13.1 
      react-dom: 16.13.1 => 16.13.1 
      react-native: https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz => 0.63.2 
      react-native-web: ~0.13.12 => 0.13.14 
    npmGlobalPackages:
      expo-cli: 4.1.4
    Expo Workflow: managed

任何帮助将不胜感激。

4

0 回答 0