Unescaped content in <script> and <style>¶
Problem. You want to put real JavaScript or CSS into a page —
content where <, >, and & mean something. Default HTML
escaping would mangle the code.
Solution. tagz already knows. The <script> and <style>
tags are created with escaping disabled.
from tagz import html
js = html.script("if (a < b && c > 0) console.log('<3');")
assert "<" in js.to_string()
assert "<" not in js.to_string()
from tagz import html
css = html.style("body > .parent { color: red; }")
assert ">" in css.to_string()
Embedding values¶
Because the content is unescaped, anything you interpolate into
a <script> block is part of the JavaScript program. Building a
script with user input is an XSS vector:
# DANGER: user_name from request is now executable JavaScript.
html.script(f"console.log('hello {user_name}');")
The safe pattern is to serialise the data with json.dumps and let
JSON encoding handle the escaping:
import json
from tagz import html
payload = {"name": "Ada"}
tag = html.script(f"window.__data__ = {json.dumps(payload)};")
assert "window.__data__" in tag.to_string()
assert '"name": "Ada"' in tag.to_string()
For especially tricky payloads (containing </script> substrings),
either base64-encode the data or split the tag boundary outside
Python — a topic well covered elsewhere.