2

Core issue:

I'm trying to grab an SVG-Inline-Object with JavaScript and send it to the Server where the output represents the given SVG-Object.

All works fine in Chrome & FF but IE (>= 9) cuts the given string of the SVG-Object anywhere, so the string sent to the server is not complete that ends up in an error.

My current process:

html

<html>
<head></head>
    <body>
        <div>
            <svg>(expect a correctly generated svg-object here - works fine)</svg>
            <a href='#export'>export</a>
            <!-- click on this link triggers the javascript-function !-->
        </div>
    </body>
</html>

javascript (triggered by click on the "export"-Link)

var $svg = $(this).parent().find("svg"); // works fine
var s = new XMLSerializer();
var svgContent = s.serializeToString($svg[0]);
$.post("/Results/saveSVG/", // saveSVG => store SVG-Data in Session
    { "svg" : svgContent }).done(function(data) {
    window.open("/Results/getSVG/svg.php");
});

/Results/saveSVG/ (a PHP-File)

$_SESSION["svg"] = $_POST["svg"]; // similar to something like this (works fine)

svg.php (works like a charm in Chrome / FF

header("Content-type: image/svg+xml");
echo $_SESSION["svg"];
exit;

What happens in Chrome / FF?

  1. svgContent-variable: <svg>...</svg>
  2. svgContent-variable received by the server (/Results/saveSVG/)
  3. output on /Results/getSVG/svg.php is a perfect SVG-File

What happens in IE?

  1. svgContent-variable is cropped somewhere: <svg>..
  2. invalid svgContent-variable received by the server (/Results/saveSVG/)
  3. output on /Results/getSVG/svg.php does not render

Debug-Information in IE

  1. svgContent-variable: (Javascript)

<svg xmlns="http://www.w3.org/2000/svg" width="263" height="300" xmlns="http://www.w3.org/2000/svg" xmlns:NS1="" NS1:xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><defs><clipPath id="DevExpress_28"><rect fill="none" stroke="none" stroke-width="0" x="0" y="0" width="263" height="300" rx="0" ry="0" /></clipPath><pattern id="DevExpressPattern_46" patternUnits="userSpaceOnUse" width="6" height="6"><path opacity="0.8" fill="none" stroke="#1498e7" stroke-width="1" d="M 0 0 L 1 1" /><path opacity="0.8" fill="none" stroke="#1498e7" stroke-width="1" d="M 5 5 L 6 6" /><path fill="none" stroke="#1498e7" stroke-width="2" d="M 0 6 L 6 0" /></pattern><pattern id="DevExpressPattern_47" patternUnits="userSpaceOnUse" width="6" height="6"><path opacity="0.8" fill="none" stroke="#7bc940" stroke-width="1" d="M 0 0 L 1 1" /><path opacity="0.8" fill="none" stroke="#7bc940" stroke-width="1" d="M 5 5 L 6 6" /><path fill="none" stroke="#7bc940" stroke-width="2" d="M 0 6 L 6 0" /></pattern><pattern id="DevExpressPattern_48" patternUnits="userSpaceOnUse" width="6" height="6"><path opacity="0.8" fill="none" stroke="#c7399a" stroke-width="1" d="M 0 0 L 1 1" /><path opacity="0.8" fill="none" stroke="#c7399a" stroke-width="1" d="M 5 5 L 6 6" /><path fill="none" stroke="#c7399a" stroke-width="2" d="M 0 6 L 6 0" /></pattern></defs><g class="series"><g class="series"><path fill="#0084d3" stroke="#ffffff" stroke-dasharray="none" stroke-linejoin="round" stroke-width="2" d="M 85.9999 229.674 A 92 92 0 0 0 224 150 L 132 150 A 0 0 0 0 1 132 150 Z" r="0" line-width="2" /><path fill="#67b52c" stroke="#ffffff" stroke-dasharray="none" stroke-linejoin="round" stroke-width="2" d="M 86 70.3256 A 92 92 0 0 0 85.9999 229.674 L 132 150 A 0 0 0 0 1 132 150 Z" r="0" line-width="2" /><path fill="#b32586" stroke="#ffffff" stroke-dasharray="none" stroke-linejoin="round" stroke-width="2" d="M 224 150 A 92 92 0 0 0 86 70.3256 L 132 150 A 0 0 0 0 1 132 150 Z" r="0" line-width="2" /></g></g><g class="labels"><g class="labels"><g><path fill="none" stroke="#0084d3" stroke-width="1" d="M 179 231 L 188 247" /><g transform="rotate(0)" x="187.9998589266569" y="246.99492667245295"><rect fill="#0084d3" stroke="none" stroke-dasharray="none" stroke-width="0" x="185" y="243" width="43" height="25" rx="0" ry="0" /><text style="font-family: 'SegoeUI', 'Segoe UI', 'HelveticaNeue', 'Helvetica Neue', 'Trebuchet MS', Verdana; font-size: 12px; font-weight: 400; fill: #ffffff;" text-anchor="start" x="192.9999" y="260"><tspan x="192.9999" dy="0">33 %</tspan></text></g></g><g><path fill="none" stroke="#67b52c" stroke-width="1" d="M 39 150.5 L 20 150.5" /><g transform="translate(6) rotate(0)" x="20.000000000042646" y="149.99990226156188"><rect fill="#67b52c" stroke="none" stroke-dasharray="none" stroke-width="0" x="-6" y="137" width="25" height="25" rx="0" ry="0" /><text style="font-family: 'SegoeUI', 'Segoe UI', 'HelveticaNeue', 'Helvetica Neue', 'Trebuchet MS', Verdana; font-size: 12px; font-weight: 400; fill: #ffffff;" text-anchor="end" x="10" y="154"><tspan x="10" dy="0">...</tspan></text></g></g><g><path fill="none" stroke="#b32586" stroke-width="1" d="M 179 69 L 188 53" /><g transform="rotate(0)" x="188.00002821465443" y="53.00517106588667"><rect fill="#b32586" stroke="none" stroke-dasharray="none" stroke-width="0" x="185" y="32" width="43" height="25" rx="0" ry="0" /><text style="font-family: 'SegoeUI', 'Segoe UI', 'HelveticaNeue', 'Helvetica Neue', 'Trebuchet MS', Verdana; font-size: 12px; font-weight: 400; fill: #ffffff;" text-anchor="start" x="193" y="49"><tspan x="193" dy="0">33 %</tspan></text></g></g></g></g><g class="dxTooltip"><path visibility="hidden" opacity="0.1" fill="#000000" stroke="none" d="M 0 0" /><path visibility="hidden" fill="black" stroke="none" d="M 0 0 Z" /><text visibility="hidden" style="font-family: 'SegoeUI-Light', 'Segoe UI Light', 'HelveticaNeue-Light', 'Helvetica Neue Light', 'SegoeUI', 'Segoe UI', 'HelveticaNeue', 'Helvetica Neue', 'Trebuchet MS', Verdana; font-size: 26px; font-weight: 200; cursor: default; fill: #ffffff; fill-opacity: 0.75;" text-anchor="middle" x="0" y="0"><tspan x="0" dy="0">0</tspan></text></g><g class="tracker"><g class="seriesTracker" /><g class="markerTracker"><path opacity="0.0001" fill="grey" stroke="none" stroke-linejoin="round" d="M 85.9999 229.674 A 92 92 0 0 0 224 150 L 132 150 A 0 0 0 0 1 132 150 Z" /><path opacity="0.0001" fill="grey" stroke="none" stroke-linejoin="round" d="M 86 70.3256 A 92 92 0 0 0 85.9999 229.674 L 132 150 A 0 0 0 0 1 132 150 Z" /><path opacity="0.0001" fill="grey" stroke="none" stroke-linejoin="round" d="M 224 150 A 92 92 0 0 0 86 70.3256 L 132 150 A 0 0 0 0 1 132 150 Z" /></g></g></svg>

  1. Same variable fully stored in the Session
  2. Output with SVG is cut:

<svg xmlns="http://www.w3.org/2000/svg" width="263" height="300" xmlns="http://www.w3.org/2000/svg" xmlns:NS1="" NS1:xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><defs><clipPath id="DevExpress_28"><rect fill="none" stroke="none" stroke-width="0" x="0" y="0" width="263" height="300" rx="0" ry="0" /></clipPath><pattern id="DevExpressPattern_46" patternUnits="userSpaceOnUse" width="6" height="6"><path opacity="0.8" fill="none" stroke="#1498e7" stroke-width="1" d="M 0 0 L 1 1" /><path opacity="0.8" fill="none" stroke="#1498e7" stroke-width="1" d="M 5 5 L 6 6" /><path fill="none" stroke="#1498e7" stroke-width="2" d="M 0 6 L 6 0" /></pattern><pattern id="DevExpressPattern_47" patternUnits="userSpaceOnUse" width="6" height="6"><path opacity="0.8" fill="none" stroke="#7bc940" stroke-width="1" d="M 0 0 L 1 1" /><path opacity="0.8" fill="none" stroke="#7bc940" stroke-width="1" d="M 5 5 L 6 6" /><path fill="none" stroke="#7bc940" stroke-width="2" d="M 0 6 L 6 0" /></pattern><pattern id="DevExpressPattern_48" patternUnits="userSpaceOnUse" width="6" height="6"><path opacity="0.8" fill="none" stroke="#c7399a" stroke-width="1" d="M 0 0 L 1 1" /><path opacity="0.8" fill="none" stroke="#c7399a" stroke-width="1" d="M 5 5 L 6 6" /><path fill="none" stroke="#c7399a" stroke-width="2" d="M 0 6 L 6 0" /></pattern></defs><g class="series"><g class="series"><path fill="#0084d3" stroke="#ffffff" stroke-dasharray="none" stroke-linejoin="round" stroke-width="2" d="M 85.9999 229.674 A 92 92 0 0 0 224 150 L 132 150 A 0 0 0 0 1 132 150 Z" r="0" line-width="2" /><path fill="#67b52c" stroke="#ffffff" stroke-dasharray="none" stroke-linejoin="round" stroke-width="2" d="M 86 70.3256 A 92 92 0 0 0 85.9999 229.674 L 132 150 A 0 0 0 0 1 132 150 Z" r="0" line-width="2" /><path fill="#b32586" stroke="#ffffff" stroke-dasharray="none" stroke-linejoin="round" stroke-width="2" d="M 224 150 A 92 92 0 0 0 86 70.3256 L 132 150 A 0 0 0 0 1 132 150 Z" r="0" line-width="2" /></g></g><g class="labels"><g class="labels"><g><path fill="none" stroke="#0084d3" stroke-width="1" d="M 179 231 L 188 247" /><g transform="rotate(0)" x="187.9998589266569" y="246.99492667245295"><rect fill="#0084d3" stroke="none" stroke-dasharray="none" stroke-width="0" x="185" y="243" width="43" height="25" rx="0" ry="0" /><text style="font-family: 'SegoeUI', 'Segoe UI', 'HelveticaNeue', 'Helvetica Neue', 'Trebuchet MS', Verdana; font-size: 12px; font-weight: 400; fill: #ffffff;" text-anchor="start" x="192.9999" y="260"><tspan x="192.9999" dy="0">33 %</tspan></text></g></g><g><path fill="none" stroke="#67b52c" stroke-width="1" d="M 39 150.5 L 20 150.5" /><g transform="translate(6) rotate(0)" x="20.000000000042646" y="149.99990226156188"><rect fill="#67b52c" stroke="none" stroke-dasharray="none" stroke-width="0" x="-6" y="137" width="25" height="25" rx="0" ry="0" /><text style="font-family: 'SegoeUI', 'Segoe UI', 'HelveticaNeue', 'Helvetica Neue', 'Trebuchet MS', Verdana; font-size: 12px; font-weight: 400; fill: #ffffff;" text-anchor="end" x="10" y="154"><tspan x="10" dy="0">...</tspan></text></g></g><g><path fill="none" stroke="#b32586" stroke-width="1" d="M 179 69 L 188 53" /><g transform="rotate(0)" x="188.00002821465443" y="53.00517106588667"><rect fill="#b32586" stroke="none" stroke-dasharray="none" stroke-width="0" x="185" y="32" width="43" height="25" rx="0" ry="0" /><text style="font-family: 'SegoeUI', 'Segoe UI', 'HelveticaNeue', 'Helvetica Neue', 'Trebuchet MS', Verdana; font-size: 12px; font-weight: 400; fill: #ffffff;" text-anchor="start" x="193" y="49"><tspan x="193" dy="0">33 %</tspan></text></g></g></g></g><g class="dxTooltip"><path visibility="hidden" opacity="0.1" fill="#000000" stroke="none" d="M 0 0" /><path visibility="hidden" fill="black" stroke="none" d="M 0 0 Z" /><text visibility="hidden" style="font-family: 'SegoeUI-Light', 'Segoe UI Light', 'HelveticaNeue-Light', 'Helvetica Neue Light', 'SegoeUI', 'Segoe UI', 'HelveticaNeue', 'Helvetica Neue', 'Trebuchet MS', Verdana;

Conclusion

the above concept works fine in chrome and ff but fails on all tested IE-Versions (9 / 10 / 11)

I've also tried to add the values into a hidden textarea and send the form to svg.php (Same effect / Chrome and FF - okay / IE fails).

Is there anything I have to adjust in the $.post-Request or is there any other concept to export an inline-SVG-Object?

the solution (thanks to timclutton - answer)

The problem caused due to a double-defined xmlns-attributes in the opening tag. Because I have no ifluence in the method where the svg-object was created, a simple str_replace did the job:

svg.php

<?
session_start();
header("Content-type: image/svg+xml");
echo str_replace("xmlns=\"http://www.w3.org/2000/svg\" xmlns:NS1=\"\" NS1:xmlns:xlink=\"http://www.w3.org/1999/xlink\"","",$_SESSION["svg"]);
?>
Community
  • 1
  • 1
wildhaber
  • 1,631
  • 1
  • 18
  • 23
  • 1
    You need to be more clear as to what the issue is - what do you mean by "cuts the string anywhere"? What do you mean by the code "failing"? We can't help debug an unclear problem. – Sam Hanley Jul 11 '14 at 13:13
  • I will update my question to be more clear. – wildhaber Jul 11 '14 at 13:16
  • 1
    Can you also give us an example of $_SESSION["svg"] value? – Filo Jul 11 '14 at 13:17
  • Thanks, @godesign. Once the details are a bit more fleshed out I'll try to help figure it out! – Sam Hanley Jul 11 '14 at 13:18
  • @Filo Thanks for your quick feedbacks, I've tried to copy some original data where the problem occurs. (Most of them are pretty sensitive data, so I had to find some where publicity doesn't matter) – wildhaber Jul 11 '14 at 14:18
  • @godesign I assume the user is able to edit the SVG inline? – Will B. Jul 11 '14 at 15:39
  • @fyrye You're right. The SVG files are representing charts and updates when the dataset is changing. We're using the chart library from DevExpress in combination of knockout.js – wildhaber Jul 11 '14 at 15:50
  • @godesign I assumed as such, I was going to suggest using the DOMDocument to validate and standardize the imported data, but seeing as how the svg is dynamic it would probably cause more harm than good. Here's an example of someone using it http://stackoverflow.com/questions/2857113/how-to-change-the-attribute-value-of-svg-file it may help you in the future for the same or similar projects when manipulating the exported data. – Will B. Jul 11 '14 at 17:29

2 Answers2

2

I've built the following from the code you posted (with minor alterations) and this works for me in IE11 and FF30 on Win8.1 x64. Perhaps try putting these two files in a folder (with jQuery, or change the src to a CDN) and see if it works for you.

File svg.php:

<?php
session_start();

if ($_POST) {
    $_SESSION['svg'] = $_POST['svg'];
    exit;
}

?>

<html>
    <head>
        <title>blah</title>
        <script type="text/javascript" src="jquery-1.11.1.min.js"></script>
        <script type="text/javascript">
            function svg(e) {
                var $svg = $(e).parent().find("svg"); // works fine
                var s = new XMLSerializer();
                var svgContent = s.serializeToString($svg[0]);
                $.post("svg.php", // saveSVG => store SVG-Data in Session
                    { "svg" : svgContent }).done(function(data) {
                    window.open("svg2.php");
                });
            }
        </script>
    </head>
    <body>
        <div>
            <svg>
                <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
            </svg>
            <a href='#export' onclick="svg(this)">export</a>
            <!-- click on this link triggers the javascript-function !-->
        </div>
    </body>
</html>

File svg2.php:

<?php
session_start();
header("Content-type: image/svg+xml");
echo $_SESSION["svg"];
exit;
?>

Update for actual SVG content

The problem seems to be with the opening tag. Changing it from...

<svg xmlns="http://www.w3.org/2000/svg" width="263" height="300" xmlns="http://www.w3.org/2000/svg" xmlns:NS1="" NS1:xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">

...to...

<svg xmlns="http://www.w3.org/2000/svg" width="263" height="300" version="1.1">

...makes it work with the code I posted above.


Update 2

Running your SVG code through the W3C Validator shows the errors. Using the modified opening tag I posted above validates successfully.

In conclusion, the problem is down to invalid XML.

timclutton
  • 12,682
  • 3
  • 33
  • 43
  • This is almost exactly the way I'm doing it. I've copied a not-sensitive example of the SVG file in my question, where the problem occurs. – wildhaber Jul 11 '14 at 14:21
  • Curious. Using your code with my pages generates an invalid XML error in both IE and FF. But removing `header("Content-type: image/svg+xml");` from second page results in a correct render. Perhaps this is an incorrect content-type? – timclutton Jul 11 '14 at 14:35
  • I've updated my post with a change to your SVG code. – timclutton Jul 11 '14 at 14:50
  • yes! you got it. Many thanks for the validation-hint. I even it's not very pretty, but I simply replace the invalid part in the opening svg-tag before echo the `$_SESSION['svg']`. This works fine now. You're effort really deserves the bounty (in 20 hours) – wildhaber Jul 11 '14 at 16:05
  • Great, glad I could help. The fix looks ugly, but if you don't control the SVG code generation then at least you found a working solution! – timclutton Jul 11 '14 at 16:34
0

Maybe it's not relevant, but have you tried this?

header("Content-type: image/svg+xml");

echo '<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' .$_SESSION["svg"];

(extracted from https://stackoverflow.com/a/1623265/3625883)

Community
  • 1
  • 1
Filo
  • 2,829
  • 1
  • 21
  • 36