vue icon indicating copy to clipboard operation
vue copied to clipboard

On SSR, script tag escaped

Open ghost opened this issue 5 years ago • 7 comments

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 = &quot;x&quot;;
            if (a &amp;&amp; x) {}
            if (a &gt; x) {}
            if (a &lt; x) {}
          </script> 

There are no restrictions on rendering script tags on the server

ghost avatar Feb 01 '19 18:02 ghost

related issue - https://github.com/vuejs/vue/issues/8829 except it's about rendering compiled templates that contains script tags

ghost avatar Feb 01 '19 18:02 ghost

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

ghost avatar Feb 01 '19 18:02 ghost

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.

LinusBorg avatar Feb 04 '19 08:02 LinusBorg

Still we can not prohibit the use of Vue as a pure server renderer, when no client hydration needed.

ghost avatar Feb 04 '19 08:02 ghost

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

ghost avatar Feb 04 '19 08:02 ghost

but if it is a supported feature, let's fix it :)

ghost avatar Feb 04 '19 08:02 ghost

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

nolimitdev avatar Feb 21 '22 11:02 nolimitdev