vscode-live-server: LiveServer breaks HTML after injecting code in fetch/response.text() with SVG content

This took me 5 hours to finally conclude LiveServer was the problem.

I have a source file of 500+ SVGs,
loaded async with fetch,
then this long string is injected into the DOM with an innerHTML statement.

Problem is LiveServer injects code into the fetch body, breaking that file with 500+ SVGs.

So I would see only part of the file… but with a different number of SVGs in the whole file I would see a different result.

I eventually slimmed the issue down to 2 SVGs

solution: LiveServer, do not inject code in files I load!

Temporary fix

Do not use fetch with .html extension , but use .xml extension

I’m submitting a…

[ ] Regression (a behavior that used to work and stopped working in a new release)
[X ] Bug report  <!-- Please search GitHub for a similar issue or PR before submitting -->
[ ] Feature request
[ ] Documentation issue or request
[ ] Other: <!-- Please describe: -->

Current behavior

LiveServer injects wrong code in last SVG, disabling all HTML that comes afterwards

Expected behavior

Display all HTML

Environment

Browser:

- [X ] Chrome (desktop) version: latest
- [X] Firefox version: latest
- [ ] Safari (desktop)
- [X] Edge version: latest

For Tooling issues:

- Live Server: 5.6.1
- Platform:  Windows
- Visual Studio Code: latest

reproduce:

liveserver_svg_bug_source.html

SVG #1:
<svg viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
    <circle cx='4' cy='4' r='2' />
</svg>
SVG #2:
<svg viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
    <circle cx='4' cy='4' r='2'/>
</svg>
<h1>NEVER SHOWN</h1>

Run this: index.html

<html>

<head>
    <style>
        svg {
            width: 30px;
            background: green;
        }
    </style>
    <script>
        addEventListener("load", () => {
            fetch("liveserver_svg_bug_source.html")
                .then(response => response.text())
                .then(html => {
                    console.error(html)
                    SVG.innerHTML = html; // fails, does not display anything after the 2nd SVG
                })
        })
    </script>
</head>

<body>
    <div id=SVG></div>
</body>

</html>

console.error output:

SVG #1:
<svg viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
    <circle cx='4' cy='4' r='2' />
<!-- Code injected by live-server -->
<script type="text/javascript">
	// <![CDATA[  <-- For SVG support
	if ('WebSocket' in window) {
		(function () {
			function refreshCSS() {
				var sheets = [].slice.call(document.getElementsByTagName("link"));
				var head = document.getElementsByTagName("head")[0];
				for (var i = 0; i < sheets.length; ++i) {
					var elem = sheets[i];
					var parent = elem.parentElement || head;
					parent.removeChild(elem);
					var rel = elem.rel;
					if (elem.href && typeof rel != "string" || rel.length == 0 || rel.toLowerCase() == "stylesheet") {
						var url = elem.href.replace(/(&|\?)_cacheOverride=\d+/, '');
						elem.href = url + (url.indexOf('?') >= 0 ? '&' : '?') + '_cacheOverride=' + (new Date().valueOf());
					}
					parent.appendChild(elem);
				}
			}
			var protocol = window.location.protocol === 'http:' ? 'ws://' : 'wss://';
			var address = protocol + window.location.host + window.location.pathname + '/ws';
			var socket = new WebSocket(address);
			socket.onmessage = function (msg) {
				if (msg.data == 'reload') window.location.reload();
				else if (msg.data == 'refreshcss') refreshCSS();
			};
			if (sessionStorage && !sessionStorage.getItem('IsThisFirstTime_Log_From_LiveServer')) {
				console.log('Live reload enabled.');
				sessionStorage.setItem('IsThisFirstTime_Log_From_LiveServer', true);
			}
		})();
	}
	else {
		console.error('Upgrade your browser. This Browser is NOT supported WebSocket for Live-Reloading.');
	}
	// ]]>
</script></svg>
SVG #2:
<svg viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
    <circle cx='4' cy='4' r='2'/>
<!-- Code injected by live-

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 24
  • Comments: 30

Commits related to this issue

Most upvoted comments

use ‘FIVE SERVER’ extension

EDIT: As of today ‘LIVE SERVER (FIVE SERVER)’ (renamed) injected code very similar to ‘LIVE SERVER’. Fixed with css rule: ‘style {display:none;}’

could anyone give me a solution for this issue please cuz i don’t know what to do .

// <![CDATA[  <-- For SVG support
if ('WebSocket' in window) {
	(function () {
		function refreshCSS() {
			var sheets = [].slice.call(document.getElementsByTagName("link"));
			var head = document.getElementsByTagName("head")[0];
			for (var i = 0; i < sheets.length; ++i) {
				var elem = sheets[i];
				var parent = elem.parentElement || head;
				parent.removeChild(elem);
				var rel = elem.rel;
				if (elem.href && typeof rel != "string" || rel.length == 0 || rel.toLowerCase() == "stylesheet") {
					var url = elem.href.replace(/(&|\?)_cacheOverride=\d+/, '');
					elem.href = url + (url.indexOf('?') >= 0 ? '&' : '?') + '_cacheOverride=' + (new Date().valueOf());
				}
				parent.appendChild(elem);
			}
		}
		var protocol = window.location.protocol === 'http:' ? 'ws://' : 'wss://';
		var address = protocol + window.location.host + window.location.pathname + '/ws';
		var socket = new WebSocket(address);
		socket.onmessage = function (msg) {
			if (msg.data == 'reload') window.location.reload();
			else if (msg.data == 'refreshcss') refreshCSS();
		};
		if (sessionStorage && !sessionStorage.getItem('IsThisFirstTime_Log_From_LiveServer')) {
			console.log('Live reload enabled.');
			sessionStorage.setItem('IsThisFirstTime_Log_From_LiveServer', true);
		}
	})();
}
else {
	console.error('Upgrade your browser. This Browser is NOT supported WebSocket for Live-Reloading.');
}
// ]]>

I’ve just experienced this too. Why is LiveServer injecting JS into the SVG when I insert it into HTML using innerHTML? This interferes with a lot of functionality, including being downloaded with the SVG when I serialize it and save it to the local or remote filesystem.

There’s already an instance of LiveServer running in the HTML, no need to inject another one into files appended with innerHTML.

Expected behavior Do not inject multiple instances of LiveServer into an HTML or SVG file.

Same problem here!

A temporary fix seems to be to rename the closing tags with a blank like so: </ svg> Modern browsers seem to auto correct this.

Five Server is also worked for me. Thank you @dawCreator.

While the problem isn’t solved, I would like to recommend you the Five Server extension same as @dawCreator. It doesn’t inject any code on your SVGs.

I opened a pull-request fix here: https://github.com/ritwickdey/vscode-live-server/pull/1195

Another workaround until the pull-request is approved is to add a boat load of spaces at the end of your file for each </svg> closing tag in your file.

I mean besides the name, it’s not that Five Server is funny… It’s that this issue was closed with the comment: “Switched to using Five Server:” Okay, sad that this isn’t maintained and that we got to switch over…

seriously? the solution is to switch over to https://github.com/yandeu/five-server… 😂🤣😅😥

Five-server also fixed my issue , related to code injecting breaking my code

Five server worked for me.

In my case, live server is clearly injecting this information into svg when served. The fix should be for live server to either inject the code correctly into svg documents or provide a configuration setting for ignored file extensions. In my case the injection errors because my svg contains svg which was not expected by the developer of this svg injection service.

A temp fix (for me) was to not use an .HTML extension, but the .XML file extension

Then I completely rewrote the https://IconMeister.github.io project and now read SVG string data from a .JSON file.