0

Alright so I'm working on a web application that stores files in an SQL Database. My problem is once I retrieve the file's blob, I need to send it through an AJAX request.

As for why I use a combination of AJAX and File Blobs, I have to provide an ACL for each file. So by locking them behind the SQL database, a user cannot type the exact path of a file to retrieve it.

I tried combining URL-Encode and Base64-Encode <?php base64_encode(urlencode($arrFile['content'])) ?>. This worked fine with an HTML file. But when it came to try a PDF file, then I got an error when downloading the file. On the JavaScript side, I tried the following to decode the Blob :

  • decodeURIComponent(atob(result.content))
  • HTML File : Came out with + symbols instead of spaces
  • PDF File : Came out unable to open
  • decodeURIComponent(atob(result.content).replace(/\+/g, " "))
  • HTML File : Came out fine
  • PDF File : Came out unable to open
  • decodeURIComponent(atob(result.content).split('').map(function(c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join(''))
  • HTML File : Came out fine
  • PDF File : Came out unable to open

Here is the PHP Encoding code:

$arrFile = $imapModel->getFile(intval($arrQueryStringParams['id']))
// $arrFile['content'] = urlencode($arrFile['content']);
$arrFile['content'] = base64_encode($arrFile['content']);

Here is the JavaScript code:

result.decoded = atob(result.content)
// result.decoded = decodeURIComponent(atob(result.content))
// result.decoded = decodeURIComponent(atob(result.content).replace(/\+/g, " "))
// result.decoded = decodeURIComponent(atob(result.content).split('').map(function(c) {
//   return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
// }).join(''))
result.blob = new Blob([result.decoded], { type: "application/octetstream" })
var isIE = false || !!document.documentMode
if(isIE){
  window.navigator.msSaveBlob(result.blob, result.filename)
} else {
  var url = window.URL || window.webkitURL
  link = url.createObjectURL(result.blob)
  var a = $(document.createElement('a')).attr("href", link).attr("download", result.filename)
  $("body").append(a)
  a[0].click()
  $("body").remove(a)
}

Expectation are simple: I'm trying to request a file's blob through an AJAX Request and trigger a Download of the file using JavaScript.

L. Ouellet
  • 133
  • 1
  • 8
  • 2
    What's the point of the `urlencode`? Just skip that!? – deceze Jan 18 '23 at 14:19
  • when I tried without the urlencode, I got all kinds of symbols inside the blob like ```Ã```. That's when I tried adding urlencode – L. Ouellet Jan 18 '23 at 14:30
  • If your blob doesn't represent text, but you're trying to look at it as text, then yeah, you'll see all sorts of random junk. – deceze Jan 18 '23 at 14:31
  • Depends on the file type. That's why I tried an HTML File and a PDF File. Plus I'm opening them with their respective software. I just tried removing the urlencoding. I can open both files, but the HTML file comes out with symbols like "ðÂ" and the PDF file comes out blank – L. Ouellet Jan 18 '23 at 14:35
  • How exactly are you "opening" the files? How do they get from a Javascript blob into their respective apps? – deceze Jan 18 '23 at 14:37
  • I added the Javascript and PHP code in the question – L. Ouellet Jan 18 '23 at 14:40
  • 1
    The problem is that `atob` alone isn't sufficient to treat binary data. I'd suggest you look into alternatives like https://stackoverflow.com/a/36183085/476, or other answers in that thread. – deceze Jan 18 '23 at 14:47
  • I did not find this thread in my initial search. Thanks a lot. it help a lot. Can I merge my question with that thread or something? – L. Ouellet Jan 18 '23 at 14:53

0 Answers0