vue
vue copied to clipboard
On SSR, script tag escaped
Version
2.5.22
Reproduction link
https://codesandbox.io/s/kx35l39lkv
Steps to reproduce
Open tab Console
What is expected?
<script data-server-rendered="true">
var a = 'a';
var x = "x";
if (a && x) {}
if (a > x) {}
if (a < x) {}
</script>
What is actually happening?
<script data-server-rendered="true">
var a = 'a';
var x = "x";
if (a && x) {}
if (a > x) {}
if (a < x) {}
</script>
There are no restrictions on rendering script
tags on the server
related issue - https://github.com/vuejs/vue/issues/8829
except it's about rendering compiled templates that contains script
tags
here - https://github.com/vuejs/vue/blob/dev/src/server/render.js#L90
the node is coming without any info, no tag, no raw, even no data, though provided attrs
via second argument
why is everything dropped down to this call?
if it would provide at least tag, we could use isPlainTextElement
beside node.raw
https://github.com/vuejs/vue/blob/dev/src/compiler/parser/html-parser.js#L30
rendering script tags isn't supported on the clientside as well, so even if it worked on the server, you would get a hydration error on the client.
Still we can not prohibit the use of Vue
as a pure server renderer, when no client hydration needed.
If rendering scripts on server is forbidden, please remove the isServerRendering
check here, as it is only introducing confusion.
https://github.com/vuejs/vue/blob/52719ccab8fccffbdf497b96d3731dc86f04c1ce/src/compiler/parser/index.js#L133
but if it is a supported feature, let's fix it :)
Possible ugly hack thanks to v-pre
directive...
<body onload="var javascripts = document.querySelectorAll('javascript'); for (var javascript of javascripts) { var script = document.createElement('script'); var type = javascript.getAttribute('type'); if (type) script.setAttribute('type', type); script.innerText = javascript.innerText; javascript.parentNode.insertBefore(script, javascript); javascript.remove(); }">
<javascript type="text/javascript" style="display: none" v-pre>
// JS code here in <javascript> tag will be switched to <script> tag (Vue does not allow to disable escaping for some element)
</javascript>
</body>
For simple server side html generation with just a few lines of javascript needed on frontend we really do not want to implement client hydration and add client.js with several hundreds of kB.
In future it will be nice to have some per-element option e.g. v-noescape
. Everyone who use it know what and why he is doing - so sane developer will not use it for user input (the same as exists v-html
- it is developer responsibility for input). I need