我已经尝试过,但似乎无法使用 UploadCare 在我的 ReactNative Expo 应用程序中上传大文件。
小于 100mb 的较小文件我使用效果很好的直接上传 API。对于大于 100mb 的文件,您需要调用多种方法来上传文件。
- 调用多部分开始端点
- 将各个部分 (5mb) 上传到分配的 s3 URL
- 调用多部分完成
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
任何帮助将不胜感激。