Yesterday, I was trying to replace an image on GitHub with another to mockup something by editing
src attribute in the browser inspector, but it didn't work because GitHub has implemented a
Content Security Policy (CSP)1 which
only allows images from certain sources:
Refused to load the image ' ' because it violates the following Content Security Policy directive: "img-src https://*.bitstrips.com 'self' data: github.githubassets.com identicons.github.com collector.githubapp.com github-cloud.s3.amazonaws.com *.githubusercontent.com".
Fortunately for what I was doing, GitHub's CSP still allows data
URLs, so I was able to
get around it by inlining my image as a data URL into the
src attribute instead of linking to an
image from another host.
Something like this was blocked:
But using a data URL like this still worked:
Creating data URLs
To create the data URL, I initially just searched for “data url generator” and checked out the first few links.
However, it then occurred to be that this wasn't something that you need to use some random and potentially shady website to do—it's basically Base64 encoding, and you can do that easily from the command line:
$ base64 < SUTD.png iVBORw0KGgoAAAANSUhEUgAAACcAAAAJAQAAAACZfgjeAAAABGdBTUEAALGPC/xhBQAAAAJiS0dEAAHdihOkAAAAB3RJTUUH4gYRBR0dahwXXQAAAD1JREFUCNdjYAgNYGFgqL8aX/+HwSE00IUFyI6N/8LAEBoaIsLwPzw0/AsDY0BoCAvD//ir4X8YGBxEQxgAzdQRP6/iZycAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTgtMDYtMTVUMjM6Mjk6MjUrMDg6MDCObV7UAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE4LTA2LTE1VDIzOjI5OjI1KzA4OjAw/zDmaAAAAABJRU5ErkJggg==
Data URLs come in the format
<mediatype> is an optional
MIME type which defaults to
;base64 is also optional but
specified when the data is Base64-encoded (which is true in our case), so just manually prepend an
appropriate header and you're good to go:
$ echo "data:image/png;base64,$(base64 < SUTD.png)" data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACcAAAAJAQAAAACZfgjeAAAABGdBTUEAALGPC/xhBQAAAAJiS0dEAAHdihOkAAAAB3RJTUUH4gYRBR0dahwXXQAAAD1JREFUCNdjYAgNYGFgqL8aX/+HwSE00IUFyI6N/8LAEBoaIsLwPzw0/AsDY0BoCAvD//ir4X8YGBxEQxgAzdQRP6/iZycAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTgtMDYtMTVUMjM6Mjk6MjUrMDg6MDCObV7UAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE4LTA2LTE1VDIzOjI5OjI1KzA4OjAw/zDmaAAAAABJRU5ErkJggg==
I'm using the
base64 tool on macOS which doesn't output line breaks by default—if you're using
base64 from GNU coreutils you'll need to pass
-w0 to disable line wrapping.
A bit more sophistication
The above worked well for the occasional conversion of PNG or JPEG images, but while writing this
post I came across this answer on the Unix & Linux Stack Exchange with a more generic solution which
made use of the
file command to automatically infer an appropriate MIME type:
Inferring the MIME type of a file:
$ file -bN --mime-type SUTD.png image/png
The author of that answer provided his own script for creating data URLs (copied verbatim from the answer):
[0 1026 8:29:38] ~ % cat $(which cssify.sh) #!/bin/sh mimetype=$(file -bN --mime-type "$1") content=$(base64 -w0 < "$1") echo "url('data:$mimetype;base64,$content')"
This also wraps the generated data URL with the CSS url()
syntax and uses the GNU coreutils version of
base64 which requires the
-w0 flag, either of which can be tweaked to your own liking.
My own version which I modified to work on macOS and added some error handling:
$ cat $(which data-url) #!/bin/sh if [ -z "$1" ]; then echo "usage: data-url file" >&2 exit 1 fi mimetype=$(file -bN --mime-type "$1") content=$(base64 < "$1") echo "data:$mimetype;base64,$content" $ data-url SUTD.png data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACcAAAAJAQAAAACZfgjeAAAABGdBTUEAALGPC/xhBQAAAAJiS0dEAAHdihOkAAAAB3RJTUUH4gYRBR0dahwXXQAAAD1JREFUCNdjYAgNYGFgqL8aX/+HwSE00IUFyI6N/8LAEBoaIsLwPzw0/AsDY0BoCAvD//ir4X8YGBxEQxgAzdQRP6/iZycAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTgtMDYtMTVUMjM6Mjk6MjUrMDg6MDCObV7UAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE4LTA2LTE1VDIzOjI5OjI1KzA4OjAw/zDmaAAAAABJRU5ErkJggg==
Wonder if I'll ever use it again though 🐣