R2 bucket upload appears corrupt upon uploading via signed URL in $.AJAX in jQuery

Hi all,

I’ve spent literally the entire day trying to get setup on R2 with a simple JS upload and I’m just not winning, any help would be greatly appreciated, thanks for your time in advance. I’ve tried Uppy along with everything else I can think of and I’m just completely stuck.

Essentially on file change for a multi file select input I generate a pre-signed URL in PHP (via an XHR request) and I can upload for multiple files.

The request gives a 200 response, all looks to be working, the file is in the bucket, correct size, MIME type, etc. although it appears to either be corrupt or I can’t work out how to access it. It’s a private bucket but when I go to the URL directly I get the error “The image “xxxxxx/logo.png”” cannot be displayed because it contains errors".

I can’t workout if that’s because the upload is corrupt and my script below is causing problems, or you’re simply not supposed to be able to access the file that way? … and if so, is there any way to view the file to confirm that the file is there and it’s not corrupt?

I’m obviously new to this, although I’m hoping to use R2, along with Cloudflare Images & Streaming to run the whole new system (which is all photos & video) I’m building through the platform… although I feel I’m stuck at the first hurdle.

I created a $.AJAX to do a GET request with a signed URL from my server (so the origin would match) directly to pull the image back down and it gave me a 200, although the image still appears to be corrupt when I look at it in preview.

Thanks so much for your help!
Anthony

// Cycles through all the files added to the file input, generates a signed URL for each server side...
$.each (files, function (index, value) {
   var file = $(this)[0];
   let fileData = new Object();
   fileData.fileName = value.name;
   fileData.fileSize = value.size;
   fileData.fileModified = value.lastModified;
   fileData.fileMimeType = value.type;
   $.post ("/api/", { function: "getSignedURL", fileData: fileData }, function (data, status)  {
        if (status == "success") {
            var response = JSON.parse (data);
            if (response.status == 1) {
                var formData = new FormData();
                formData.append ('fileUpload', file);
                $.ajax ({
                    cache: false,
                    contentType: fileData.fileMimeType,
                    data: formData,
                    enctype: 'multipart/form-data',
                    processData: false,
                    type: 'PUT',
                    url: response.url,
                    success: function (result) {
                         // Do something with the result
                         console.log ('Request succeeded...');
                         console.log (result);

})})})}; // etc

From my understanding if I’m viewing the link on a custom domain, the contents are public… so that would mean I should just be able to open the URL in a web browser and see the image? Since that is not working, you would then assume that the file is somehow becoming corrupt when it’s getting uploaded?

Once again, thank you for your time!

I managed to solve this (after many frustrating hours) it and thought I’d post my finding in case anyone finds this with something similar.

The biggest thing to note is that when I was viewing the outcome of the upload in the browser, because I was using the same file to test with and the upload result was the same URL in Cloudflare; I was seeing the CACHED results from Cloudflare… so adding a parameter i.e. ?v=1 to the end gave me the most recent uploaded version… once I realised this, it was easy to see what was actually getting uploaded and fixing it was easy.

So while I was testing I likely already had the fix many times, but kept seeing the wrong output in testing.

I tried fileReader () and converting to Blob and uploading, which as it turns out actually worked but was unnecessary… you can just upload the file directly.

Here was my final code:

$(‘#JS-fileUploadInput’).on (‘change’, function (e) {
e.preventDefault ();
let files = this.files;
$.each (files, function (index, value) {
let file = $(value)[0];
let fileData = new Object();
fileData.fileName = value.name;
fileData.fileSize = value.size;
fileData.fileModified = value.lastModified;
fileData.fileMimeType = value.type;
$.post (“/api/”, { function: “r2SignedURLGet”, fileData: fileData }, function (data, status) {
if (status == “success”) {
let response = JSON.parse (data);
if (response.status == 1) {
$.ajax ({
cache: false,
contentType: false,
data: file,
enctype: false,
processData: false,
type: ‘PUT’,
url: response.url,
success: function (result) {
// Do something with the result
console.log (‘Request succeeded…’);
},
fail: function (result) {
console.log (‘Request failed…’);
}
});
}
}
});
})
});

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.