eligrey / eligrey/FileSaver.js

Downloading jpeg on Chrome iOS only results in 1) opening image in new tab or 2) downloading file named "document" with no extension

Open
#686 11 comments 9 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
22k
Forks
4.3k
PR merge metrics
No merged PRs in 30d

Description

Hello, I am having trouble downloading an image on Chrome iOS 87.0.4280.77. I am using an iPhone 12 running iOS 14.3-beta. I am taking a screenshot with MediaRecorder and then creating a blob with `const currentBlob = new Blob([buffer], {type: 'image/jpeg'})`. My goal is to be able to trigger a download of the image, with the name and file extension set.

### Issue: Testing with FileSaver.js with code from `v2.0.4` or `master`
When I call `saveAs(currentBlob, "name.jpg")`, the file pops up in a new tab. I can long press on it and get the ability to save to photos (and other things), but I want a direct download.

For both versions of FileSaver.js I have tried changing the type of the blob (b/c I have read that may force Chrome to automatically download the file), but that results in no tab being opened and no download pop-up:
```
const currentBlob = new Blob([buffer], {type: 'image/jpeg'})
const rawBlob = new Blob([currentBlob])
const octetBlob = new Blob([currentBlob], {type: 'application/octet-stream'})
saveAs(blob / rawBlob / octetBlob, "name.jpg")
```
For contrast, Safari iOS shows the system dialog for a download in all three of these cases, with both versions of FileSaver.js.

### Solution Attempt 1: Using `a` to download the image
The basic way to download a file is below. This results in the image being opened in a new window with no download prompt:
```
const currentBlob = new Blob([buffer], {type: 'image/jpeg'})
const a = document.createElement('a')
a.download = currentName
a.href = URL.createObjectURL(currentBlob)
a.rel = 'noopener'
document.body.appendChild(a)
click(a)
document.body.removeChild(a)
```

If I instead encode the Blob into a Base64 encoded string with [`readAsDataURL`](https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL), I can get the file to download, but it is named 'document' and has no file extension (though if I rename the file to "name.jpg" then I can see it is in fact an image):
```
const currentBlob = new Blob([buffer], {type: 'image/jpeg'})
const reader = new FileReader()
reader.onloadend = () => {
const a = document.createElement('a')
a.download = currentName
a.href = reader.result // I.e. data:image/jpeg;base64,/9j/4AA...
a.rel = 'noopener'
document.body.appendChild(a)
click(a)
document.body.removeChild(a)
}
reader.readAsDataURL(currentBlob)
```
alt text
alt text

I have also tried changing the Base64 encoded string in several ways to try to rename the file, but to no effect.
```
reader.onloadend = () => {
...
const url = reader.result
const urlWithHeaders = url.replace(';', `;name=${currentFilename};headers=Content-Disposition%3A%20attachment%3B%20filename=%22${currentFilename}%22;`)
const urlFile = url.replace(/^data:[^;]*;/, 'data:attachment/file;')
const urlOctet = url.replace('image/jpeg', 'binary/octet-stream')
a.href = url / urlWithHeaders / urlFile / urlOctet
...
}
```

### Solution Attempt 2: Using a new window
I have also tried by opening a new window, but it just opens the image in a new window and does not prompt a download:
```
const currentBlob = new Blob([buffer], {type: 'image/jpeg'})
const newWindow = window.open(URL.createObjectURL(currentBlob), '_blank')
```

### Questions
* Is Chrome iOS downloading supported with FileSaver.js?
* Is this a known limitation of Chrome iOS?

There are several issues that seem potentially related, but all of them are quite old and haven't focused on images specifically: https://github.com/eligrey/FileSaver.js/issues/506, https://github.com/eligrey/FileSaver.js/issues/576, https://github.com/eligrey/FileSaver.js/issues/343

I have also tried with an mp4 but, just like these questions describe, it is not working:
- https://stackoverflow.com/questions/63848034/anchor-download-attribute-created-with-javascript-not-working-on-ios-chrome
- https://stackoverflow.com/questions/64969672/unable-to-download-files-with-the-correct-name-in-chrome-on-ios

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.