0

I store SVG files as data URIs in MySQL. Later I want to display the SVGs as images again using the CSS background-image property.

This is how I produce the data URI (following this answer).

// SVG element
let svg = document.getElementById('tree-svg');

// SVG as string
let serializer = new XMLSerializer();
let svgSource = serializer.serializeToString(svg);

// Add name spaces
if (! svgSource.match(/^<svg[^>]+xmlns = "http\:\/\/www\.w3\.org\/2000\/svg"/)) {
    svgSource = svgSource.replace(/^<svg/, '<svg xmlns="http://www.w3.org/2000/svg"');
}
if (! svgSource.match(/^<svg[^>] + "http\:\/\/www\.w3\.org\/1999\/xlink"/)) {
    svgSource = svgSource.replace(/^<svg/, '<svg xmlns:xlink="http://www.w3.org/1999/xlink"');
}

// XML declaration
svgSource = '<?xml version="1.0" standalone="no"?>\r\n' + svgSource;

// data URI
let svgUri = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svgSource);

I store svgUri as a blob in MySQL. This is a sample string representing a simple SVG:

data:image/svg+xml;charset=utf-8,%3C%3Fxml%20version%3D%221.0%22%20standalone%3D%22no%22%3F%3E%0D%0A%3Csvg%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20id%3D%22tree-svg%22%20viewBox%3D%220%200%20700%20500%22%3E%3Cg%20transform%3D%22translate(40%2C%2040)%22%3E%3Ctext%20class%3D%22node-text%22%20y%3D%2220%22%20x%3D%2223.192203521728516%22%20id%3D%22n0%22%3Eone%3Ctspan%20class%3D%22node-subscript%22%3E1%3C%2Ftspan%3E%3C%2Ftext%3E%3Cline%20x1%3D%2223.192203521728516%22%20y1%3D%2240%22%20stroke-width%3D%222%22%20id%3D%22n0%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E

This is the CSS to display the SVG as an image (this is Blade template syntax, but as I can see in dev tools, the string from my database is rendered correctly between the parentheses):

edit: I added the quotes in the below code sample after reading a comment. It's working now.

background-image: url("{!! $sentence['svg'] !!}")

This doesn't work yet, nothing is rendered. The div I attach the background image to is empty. If I paste the string from MySQL to a URL bar, the SVG is displayed correctly.

What do I need to change in my JS code and or in CSS to display the SVG as background-image?

Pida
  • 928
  • 9
  • 32
  • 2
    The [referenced answer](https://stackoverflow.com/a/23218877) contains a call to `encodeURIComponent` which you seem to be missing. Data URIs are URIs and must be valid as such. Typical SVG code contains many chars that are not valid or have special meaning in URIs unless escaped. – Raphael Schweikert Oct 30 '19 at 22:36
  • Thanks, I wasn't aware I missed a line from that answer. When adding it, the string I store is changed (for example `` becomes `"%3C%3Fxml%20version%3D%221.0%22%20standalone%3D%22no%22%3F%3E"`), but my problem remains. – Pida Oct 30 '19 at 22:48
  • 2
    “I also tried prefixing the svg variable above with `data:image/svg+xml;charset=utf-8,`, which didn't help” – this, too, is a must. If you paste that entire string to the URL bar, it should display the SVG. If it doesn’t, using it in CSS can’t work either. Also try surrounding the URL with quotes in the CSS `url` function. – Raphael Schweikert Oct 31 '19 at 06:23

0 Answers0