Reputation: 918
I experienced a bug where svg images could not be shown on Safari. After investigating I realized it was due to the fact that I load ressources as packs/archives of files that I split in the browser.
When I load the ressources, I get a plain text blob. I use blob.slice() to extract a ressource, passing the correct MIME type. However, it seems that the new blob does not have the correct MIME type but still the old one (plain text). On Chrome and Firefox, it turns out that the image can be displayed even if its MIME type is incorrect but not on Safari.
Here is the code which does not work:
const blob = new Blob([ressource], {
type: "text/plain",
});
const slicedBlob = blob.slice(0, blob.size, "image/svg+xml");
// slicedBlob.type is "text/plain"
I also reproduced some minimal test cases: https://jsbin.com/yavaxadalo/edit?js,output
From the MDN docs and the W3C specs it looks that I use the method as it is intended too, but maybe I am missing something ?
Upvotes: 4
Views: 3882
Reputation: 136707
I have to admit I am a bit clueless about this Safari's bug. This should probably be reported.
I'd like to point out that your jsbin was a bit misleading, since the Blob returned by the slice method correctly has its type
set to 'image/svg+xml'
(you were logging the type of the original blob2
), but this just makes things even weirder...
Now, I'm not too clear as to why you want to use Blob.slice here, if you just want to change the type of that Blob, then you can simply create a new one using the Blob()
constructor which also accepts other Blobs as blobType.
const blob1 = new Blob([
`<svg xmlns="http://www.w3.org/2000/svg">
<rect width="100" height="100"/>
</svg>`
], {type: 'text/plain'});
console.log(blob1.type);
const blob2 = new Blob([blob1], {type: 'image/svg+xml'});
console.log(blob2.type);
img.src = URL.createObjectURL(blob2);
<img id="img">
And if you really wish to use the Blob.slice method, then as a workaround, you can create a new one from the Blob constructor which will wrap it correctly:
const blob1 = new Blob([
`<svg xmlns="http://www.w3.org/2000/svg">
<rect width="100" height="100"/>
</svg>[BAD-DATA]`
], {type: 'text/plain'});
// if we need to slice it
const sliced = blob1.slice(0, blob1.size - '[BAD-DATA]'.length);
// wrap it again for Safari...
const blob2 = new Blob([sliced], {type: 'image/svg+xml'});
img.src = URL.createObjectURL(blob2);
<img id="img">
Upvotes: 4