here is my code, work well on Chrome56:
function dataURItoFile(dataURI, filename) {
const mimeType = dataURI.split(',')[0].split(':')[1].split(';')[0]
return fetch(dataURI)
.then(res => res.arrayBuffer())
.then(buf => new File([buf], filename, { type: mimeType }))
}
dataURI: base64 string
but on Safari10:
XMLHttpRequest cannot load data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAQACAYAAAAXy/6SAAAAAXNSR0IArs4c6QAAQABJREFUeAHsXQlAVcUa/tgXUQRBRVLQm6KIIhpaUmkmUoqllWgmlgaZTzKXXF+Z+so1rQif+iA3zFwqNckyjFzCXFJEFEXFVERQUARRdnjfnLtw2ZQ2QJ1fuWfOnDlzZr5zzpyZb/75f4O2bT1KIEUiIBGQCEgEqkTg1KmYKo/dzwf4fbifqyfrJhGQCEgEJAISAYmAREAiIBGQCEgEJAISAYlADSBgWAPXkJeQCEgEJAISAYmAREAiIBGQCEgEJAISAYmAREAiIBGQCEgEJAISgQcQAUlAP4A3XVZZIiARkAhIBCQCEgGJgERAIiARkAhIBCQCEgGJgERAIiARkAjUBAKSgK4JlOU1JAISAYmAREAiIBGQCEgEJAISAYmAREAiIBGQCEgEJAISAYnAA4iAJKAfwJsuqywRkAhIBCQCEgGJgERAIiARkAhIBCQCEgGJgERAIiARkAhIBGoCAUlA1wTK8hoSAYmAREAiIBGQCEgEJAISAYmAREAiIBGQCEgEJAISAYmAROABREAS0A/gTZdVlghIBCQCEgGJgERAIiARkAhIBCQCEgGJgERAIiARkAhIBCQCNYGAJKBrAmV5DYmAREAiIBGQCEgEJAISAYmAREAiIBGQCEgEJAISAYmAREAi8AAiIAnoB/CmyypLBCQCEgGJgERAIiARkAhIBCQCEgGJgERAIiARkAhIBCQCEoGaQMC4Ji4ir/FgI2DYsBGMW7WDkaqtsjVu1RYGVg1QfPUyiq4ko+jS78g/8DMKz54ASkoebLBk7SUCEgGJgERAIiARkAhIBCQCEgGJgERAIiARkAhIBCQC9xECBm3bekjG7z66oXWpKkaOzrAcOgamjz1drWIV/p6A7MXTUJR8vlrpZSKJQE0hcOpUTE1dqk5dh9+HOlUeWRiJgERAIiARkAhIBCQCEgGJgERAIiARkAhIBO49BKQG9L13z+p+iY2MYPHCSFj6BQJG1X/Eis6dQtHli3W/frKEEgGJgERAIiARkAhIBCQCEgGJgERAIiARkAhIBCQCEgGJQLUQqD47WK3sZKIHHQEDE1NYTVoI00ee+ENQ5O3cguylH9AER/EfOk8mlghIBCQCEgGJgERAIiARkAhIBCQCEgGJgERAIiARkAhIBOouAtIJYd29N/dkyeqNmVG3yWf3HujvZVMtbO1UTlDxz65aqUsTefX3gXvprgxJBCQCEgGJgERAIiARkAhIBCQCEgGJgERAIiARkAhIBB5YBKQG9AN76//+ipv7vASzJ/v+oYzzdm6m5vOHf1Lz2RNhUYvQ5vZZ/LJvF37+bhsiYzOquL4rpi99Dy/3dIExCvF65BpMHBuCxCpSQxWIbyNGQ1DVx8NGYdCiQ7qUXsMnYFzAS3CzuYz3O7yEjbojDNgNxtwFU2C/4D9IifkGgUPnVX0N/fNkWCIgEZAISAQkAhIBiYBEQCIgEZAISAQkAn8RgTYqR7w1sj+6d3WFpYXZX8ytbp5eWFiEmLhELFu9Hft+O1k3CylLJRGQCJRBQBLQZeCQO38WAUO7prB8dfwfOl1tduPPks9AYNgH8HKw4jU....
so, is that a bug?
It boils down to this code:
url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
xhr = new XMLHttpRequest
xhr.open('GET', url)
xhr.send()

When sortering the url i saw the full error message:
XMLHttpRequest cannot load < URL >. Cross origin requests are only supported for HTTP.
I tested the same code in Safari TP and it worked just fine. So did the native fetch version of your code also.
Use any other way to make a File out of a base64. Make your pick: http://stackoverflow.com/questions/16245767/creating-a-blob-from-a-base64-string-in-javascript
using blob instead of arraybuffer yields a better result, you don't have to get the mimeType from the base64 since it will be included when you return the blob. Beside blob may also be a better choice for you since you can't construct files on all browsers (see note 2 on caniuse.com)
return fetch(dataURI)
.then(res => res.blob())
.then(blob => new File([blob], filename, { type: blob.type }))
Parse the url, see if it's a data URI and if it's convert the data URI to a blob internally without using xhr
Thank you!
@jimmywarting Thanks for your extensive research. Do you think this is something we should aim to fix in our polyfill? If not, I'm keen on closing this out.
I'm on the fence.
It would be nice if it worked but I also thing its a bad practise to have a base64 URL to begin with.
Think you should always aim to have a arrays buffers or blob. Decoding and encoding is only a unnecessary overhead and there are better ways to handle it IMAO
I would agree on a workaround if it was easy (e.g. 2–3 lines of code). However, since the logic to convert a base64 would inflate the size of this polyfill, I don't think this is something that we should be working around of, and instead it should be the responsibility of the user to avoid using fetch() for this on unsupporting browsers.
Most helpful comment
The problem
It boils down to this code:
When sortering the url i saw the full error message:
I tested the same code in Safari TP and it worked just fine. So did the native fetch version of your code also.
Workaround
Use any other way to make a File out of a base64. Make your pick: http://stackoverflow.com/questions/16245767/creating-a-blob-from-a-base64-string-in-javascript
Code review
using blob instead of arraybuffer yields a better result, you don't have to get the mimeType from the base64 since it will be included when you return the blob. Beside blob may also be a better choice for you since you can't construct files on all browsers (see note 2 on caniuse.com)
What can the polyfill do to fix it?
Parse the url, see if it's a data URI and if it's convert the data URI to a blob internally without using xhr