Hi, I need to upload user submitted files to Dropbox, and because I can’t pass File objects from Frontend to Backend modules/functions I have resolved to using Fetch to Dropbox endpoints (E.g. - https://content.dropboxapi.com/2/files/upload) to upload the files.
Dropbox uses 2 different endpoints for submitting files under 150 mb and files over 150 mb . I’ve succeeded in uploading files <150 mb to this endpoint - https://content.dropboxapi.com/2/files/upload
However, I’ve failed multiple trials in uploading files >150 mb with fetch to this endpoint -
- https://content.dropboxapi.com/2/files/upload_session/start
- https://content.dropboxapi.com/2/files/upload_session/append_v2
- https://content.dropboxapi.com/2/files/upload_session/finish
All I get in the response is ‘TypeError:Failed to fetch’. I don’t understand why all my other Fetch (post) requests have succeeded without a hitch, yet doesn’t work at all towards this specific endpoint. The endpoint URL is accurate.
My code for this fetch request is below if anyone would like to inspect it and tell me where I got it wrong. Thanks in advance for reading this long post, really need help with this one.
export function fetch_uploadDbx(file, filename) {
const UPLOAD_FILE_SIZE_LIMIT = 150 * 1024 * 1024 ;
console.log( "Uploading " + filename + " to Dbx . . ." )
if (file.size < UPLOAD_FILE_SIZE_LIMIT) {
return fetch(dbxURL, {
"method" : "post" ,
"headers" : {
"Authorization" : "Bearer *ACCESS_TOKEN*" ,
"Content-Type" : "application/octet-stream" ,
"Dropbox-API-Arg" : "{\"path\":\"/render/" + filename + "\",\"mode\": {\".tag\":\"add\"}}"
},
"body" : file
})
.then((httpResponse) => {
if (httpResponse.ok){
console.log( "HTTP RES : OK" )
console.log( "Uploaded " + filename + " to Dropbox." );
return httpResponse.ok
} **else** {
console.log( "HTTP RES : NOT OK" )
console.log( "[ERROR] " + filename + " failed to upload." )
return !httpResponse.ok
}
})
. catch (err => console.log( "ERROR : " + err));
} **else** {
const maxBlob = 8 * 1000 * 1000 ;
var workItems = [];
var offset = 0 ;
var sessionID;
// Slice the file into chunks for upload session
**while** (offset < file.size) {
var chunkSize = Math.min(maxBlob, file.size - offset);
workItems.push(file.slice(offset, offset + chunkSize));
offset += chunkSize;
}
const task = workItems.reduce((acc, blob, idx, items) => {
if (idx == 0 ) {
// Start multipart upload of file
return acc.then( function () {
return fetch(dbxURL_start, {
"method" : "post" ,
"headers" : {
"Authorization" : "Bearer *ACCESS_TOKEN*" ,
"Content-Type" : "application/octet-stream" ,
"Dropbox-API-Arg" : "{\"close\":false}"
},
"body" : blob
})
.then((response) => {
sessionID = response.session_id
})
. catch (err => console.log( "[ERROR] UPLOAD_SESSION_START : " + err));
})
} **else if** (idx < items.length- 1 ) {
// Append part to the upload session
return acc.then( function (sessionID) {
return fetch(dbxURL_append, {
“method” : “post” ,
“headers” : {
“Authorization” : “Bearer ACCESS_TOKEN” ,
“Content-Type” : “application/octet-stream” ,
“Dropbox-API-Arg” : “{"cursor": {"session_id": "” + sessionID + “","offset":"” + (idx * maxBlob) + “"},"close":false}”
},
“body” : blob
})
.then(() => sessionID)
. catch (err => console.log( "[ERROR] UPLOAD_SESSION_APPEND : " + err));
})
} else {
// Last chunk of data, close upload session
return acc.then( function (sessionID) {
return fetch(dbxURL_finish, {
"method" : "post" ,
"headers" : {
"Authorization" : "Bearer *ACCESS_TOKEN*" ,
"Content-Type" : "application/octet-stream" ,
"Dropbox-API-Arg" : "{\"cursor\": {\"session_id\": \"" + sessionID + "\",\"offset\":\"" + (file.size - blob.size) + "\"},\"commit\": {\"path\":\"/render/" + filename + "\",\"mode\":{\".tag\":\"add\"}}, \"close\":true}"
},
"body" : blob
})
.then((httpResponse) => {
if (httpResponse.ok){
console.log( "HTTP RES : OK" )
return httpResponse.ok
} **else** {
console.log( "HTTP RES : NOT OK" )
return !httpResponse.ok
}
})
. catch (err => console.log( "[ERROR] UPLOAD_SESSION_FINISH : " + err));
})
}
}, Promise.resolve());
}
}