Open bsjaffer opened 4 years ago
@tong233 A sample code as to how to use your library would be extremely helpful
@bsjaffer Were you able to make this work?
@bsjaffer Sorry for the late reply, before addFile() you need convert native File to Blob:
const blob = await fetch(file.uri).then(res => res.blob());
r.addFile(blob);
r.upload();
@bsjaffer sample example
componentDidMount() {
this.inintResumable()
}
inintResumable = () => {
const option = {
withCredentials: true,
chunkNumberParameterName: 'chunk',
totalSizeParameterName: 'size',
typeParameterName: 'type',
fileNameParameterName: 'fileName',
relativePathParameterName: 'md5', // relativePath as md5 for server
totalChunksParameterName: 'chunks',
target: uploadPath,
testChunks: false,
chunkSize: 1024 * 1024,
forceChunkSize: true,
simultaneousUploads: 5,
maxChunkRetries: 3,
chunkRetryInterval: 500,
allowDuplicateUploads: true,
method: 'octet',
xhrTimeout: 30 * 1000,
}
this.resumable = new Resumable(option)
this.resumable.on('fileAdded', (file, event) => {
this.getMaxChunkNumber(file)
})
this.resumable.on('fileSuccess', (file, message) => {
this.closeFileBlob()
})
this.resumable.on('error', (message, file) => {
this.closeFileBlob()
})
this.resumable.on('timeout', (message, file) => {
this.closeFileBlob()
})
this.resumable.on('fileProgress', (file, message) => {
const progress = file.progress()
console.log(progress)
})
}
// Get the maximum number of chunks of the file exists on the server
getMaxChunkNumber = async file => {
try {
const data = {
fileName: file.fileName,
md5: file.relativePath,
ext: file.type
}
const res = await requestMaxChunkNumber(data)
if (res.number) {
file.markChunksCompleted(res.number || 0) // mark the resume transfer from the nth block
}
this.resumable.upload()
} catch (error) {
}
}
// get file for example via react-native-syan-image-picker react-native-document-picker
upload = async (file) => {
this.blob = await fetch(file.uri).then(res => res.blob()) // convert native file to blob
this.blob.name = this.blob._data.name
// import RNFS from 'react-native-fs'
const md5 = await RNFS.hash(file.uri, 'md5')
this.blob.relativePath = md5 // relativePath as md5
this.resumable.addFile(this.blob)
}
closeFileBlob = () => {
if (this.blob instanceof Blob) {
try {
this.blob.close() // close blob destroy memory
} catch (error) {
console.warn('close blob error', error)
}
}
}
@tong233 Man... Did you try to use the default 'multipart' method too? My server is already setted up to accept that, so i didn't want to change it now, since i have a JS client too using multipart...
When i tried, first i got the following error:
[TypeError: data.close is not a function. (In 'data.close()', 'data.close' is undefined)]
Which is caused by line 919 of the lib's code, since he/she tries to close the FormData instead of the Blob file... To fix this, since i didnt want to fork the code, i added the following code to my main index.js
window.FormData.prototype.close = () => {};
After doing this, i noticed that the Blob generated by the fetch doesn't get the right mimeType setted... So to fix this, i changed the fetch call to use this function that i found on google:
function urlToBlob(url) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.onerror = reject;
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
resolve(xhr.response);
}
};
xhr.open('GET', url);
xhr.responseType = 'blob'; // convert type
xhr.send();
});
}
And then, finally, i noticed that the xhr
isn't adding the right Content-Type, with the boundary, to the request made by this lib ;___; I tried A LOT of things today and couldn't find any way to fix this... I keep getting a $.xhr.responseText of:
type == null
I think that the problem should be in the native code of react native, maybe? Cause the Blob part generated by FormData seems to be right:
{
"part":{
"_data":{
"__collector":[
"Object"
],
"blobId":"17db3c43-4ebe-4fde-afb6-d8499cc2cf5b",
"lastModified":"undefined",
"offset":0,
"size":579340,
"type":"image/jpeg"
},
"fieldName":"file",
"headers":{
"content-disposition":"form-data; name=\"file\"",
"content-type":"image/jpeg"
}
}
}
Maybe anyone has any ideas? ;/
I am trying to use resumable js to upload fine , but i am getting files added event but i am not getting any error or upload progress , am i missing something here?