8 ms·
For those like me who needed a little help... I do not fully understand the browser rendering process (someone who does please chime in), but what I gather abou
by bogidon 6y ago
For those like me who needed a little help... I do not fully understand the browser rendering process (someone who does please chime in), but what I gather about how this is works is:
- the content-type of the page is "text/html", so the browser is trying to render html
- there is no special meaning of the #render key to the browser (again the browser doesn't know this is json)
- browsers are very fault tolerant so they'll just skip over your document till they find pieces of html
- the JS made by the author is the part that parses the json as json, and it uses the #render key as its metadata section
You can try opening a file like this to test for yourself to get a sense of just the browser-parsing part, test.html:
{
"test": "hello",
"myHtml": "<html><meta charset=utf-8><h1>Hello World</h1></html>"
}
I do however get this warning in FireFox so perhaps this is pretty fragile:
> The character encoding declaration of the HTML document was not found when prescanning the first 1024 bytes of the file. When viewed in a differently-configured browser, this page will reload automatically. The encoding declaration needs to be moved to be within the first 1024 bytes of the file.
I'm guessing differently-configured means not in quirks mode? Does quirks mode just make the browser extra fault tolerant?
- pjgalbraith 6y agoIn regards to the character encoding issue, I wonder if they could just move the #render to the top of the object by inserting it as the first property.
- mstade 6y agoI'm guessing there might be issues with the streaming nature of html parsers then. If you put it at the top and the JSON is of any non-trivial size you might end up with the script trying to read invalid JSON since it's not fully loaded yet.
- jammaloo 6y agoThe script could be tied into the global onload event, so that it will only attempt to parse the JSON after the page has been fully loaded. Likely the HTML block is just placed at the bottom of the JSON for aesthetic reasons.
- pjgalbraith 6y agoThey could just add the "defer" attribute on the script tag to prevent that.
- deleted 6y ago[deleted]
- gpnt 6y agoI don't see this error on FF. Are you seeing this on the console? I put the meta tag to render some special characters without relying on the server, but HTTP header would be a better option (Content-Type: text/html; charset=utf-8). And you nailed the process.
- bogidon 6y agoHey! Yes, however now I notice that this is only when running locally. I took your page, replaced script and css with absolute links, and loaded locally as file://
- gpnt 6y agohmm, I didn't find this error locally either. I will try using file://. Thanks for the report. Also, if you are interested, the project is on GitHub: https://github.com/webdatarender https://github.com/webdatarender
- missblit 6y agoThe reason it works locally is because charset detection works different when loading from a local file than when loading from a webserver. In particular browsers tend to be a lot more enthusiastic about treating local files as unicode than they are for responses from web servers. The reason the meta charset doesn't pick up is you're missing quotes around `utf-8` (also it may be past the 1024 byte mark, hard to say without running wc).
- necovek 6y agoThe reason browsers' charset autodetection works differently locally is likely because HTTP standard specifies Latin1 (ISO-8859-1) as the default encoding (at least in 1.1).
- myfonj 6y agoOr server sends explicit charset in HTTP header (`Content-Type: text/html; charset=UTF-8`), so meta element override is not needed at all. Naturally, there is no such header present in file:///.
- greggman3 6y agoYou are correct. It's a silly hack. Just because it happens to work doesn't make it a good idea. Turn off JavaScript and you just get JSON text.
- Kalium 6y ago> Just because it happens to work doesn't make it a good idea. An oft-unheard voice of wisdom and sane engineering practices speaks. Hark, ye mortals.
- pwdisswordfish4 6y agoThis but unironically.
- deleted 6y ago[deleted]
- CGamesPlay 6y agoHere's one that works without JavaScript, you curmudgeon: data:text/html;charset=utf-8,%7B%20%22foo%22%3A%20%22bar%22%2C%20%22baz%22%3A%20%5B%20%22qux%22%20%5D%2C%20%22%23render%22%3A%20%22%3Chtml%3E%3Cbody%3E%3Cdiv%20id%3Dcontent%3E%3Ch1%3EMy%20fancy%20document%3C%2Fh1%3E%3Cp%3EThis%20is%20a%20completely%20%26quot%3Bnormal%26quot%3B%20HTML%20document.%3C%2Fp%3E%3C%2Fdiv%3E%3Cstyle%3Ebody%20%7B%20visibility%3A%20hidden%3B%20%7D%20%23content%20%7B%20visibility%3A%20initial%3B%20position%3A%20absolute%3B%20top%3A%200%3B%20%7D%3C%2Fstyle%3E%3C%2Fbody%3E%3C%2Fhtml%3E%22%20%7D You can paste this directly into your URL bar, and view source to see the valid JSON document.
- Arnavion 6y agoIt's a valid JSON document that's basically unrelated to the HTML that ends up being displayed, so it's not exactly equivalent to the submitted link. What the submitted link achieves is impossible without JS, which is also why it's a cute hack and should only be used in production with the knowledge that it's not going to work well for clients without JS.
- 6y ago
- globular-toast 6y agoIn Firefox it renders in "quirks mode" because it can't find a standards compliant page. There used to be downsides to the page rendering in quirks mode instead of standards compliant mode, but I'm not sure any more.
- myfonj 6y agoHere is the trick in a datauri nutshell: data:text/html,{"data":"Hello.","whatever":"<script>onload=function(){document.body.innerHTML='<h1>'+JSON.parse(document.body.innerHTML).data+'</h1>'}</script>"}
- bzbarsky 6y agoYou first two bullet points are correct. For the third one, there's no "skipping over" involved. The <html> and <body> opening tags are optional in HTML. The browser sees some non-whitespace text (the opening '{') not in the context of any other tag, auto-opens those tags, and the text starts being parsed as body text. If the page loaded slowly enough, over multiple packets that arrived separated in time, you would see the JSON text coming in and rendering as text, with all the curlies and all, until the browser gets to the <html hidden> part of the JSON. At that point, some common-error fixup dating back to the Netscape/IE 3 days kicks in: when you see an <html> or <body> tag and one has already been opened (due to some stray content at the beginning of the file, likely), you don't open a new one, but copy the attributes to the existing one. This copies the "hidden" attribute to the <html>, which hides it. After that either the script executes and does its work, per your fourth bullet point, or script is disabled and the style rule inside <noscript> unhides the <html> element, but at that point you will of course just see the JSON text, parsed as HTML. > I do however get this warning in FireFox so perhaps this is pretty fragile: I'm not sure whether the site changed since then, but now it's sending `charset=utf-8` in the content-type header, so there's no meta prescan at all. Which is what allows the emoji after "Need Help?" to be decoded correctly. Were you seeing the meta prescan warning on your local test file, or on the site itself? > I'm guessing differently-configured means not in quirks mode? No, it means things like preferences about how to handle pages without encoding declarations via various heuristics (e.g. scanning byte value frequencies and guessing what character encoding is in use based on that). Quirks mode is determined solely by the doctype of the page. This page has no doctype (since it starts with a '{'), so it's always in quirks mode. And what quirks mode does is enable a set of behaviors designed to not break content written more or less in the "before HTML 4.0" era. https://quirks.spec.whatwg.org/ https://quirks.spec.whatwg.org/ should have a more or less exhaustive list of quirks mode behaviors browsers are expected to implement. Some of these are extra-fault-tolerance (e.g. the hashless hex color and unitless length quirks), while some are just replicating pre-CSS browser rendering behavior (like the line height calculation quirk, which a bunch of sliced-image stuff relies/relied on).