Trouble with script embedding in a widget.

Technical Support
  • Hi, I'm working on my NodeBB forum configuration (under NodeBB 0.8.2).
    I installed the plugin nodebb-plugin-custom-pages
    then created a new template page (named sondage.tpl)
    and added in my Content section a js script (between script tags) :

    <script type="text/javascript" charset="utf-8" src=""></script>

    My problem is when the page is loading, I get this error in the console :
    Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.

    So, the script can't succeed in writing into the document. How can I fix this ?
    Thank you for your help !! 🙂

  • That script just isn't compatible with async loading.

    You could embed it into an iframe though. It's ugly, and you'll need to adjust the width height and border manully, but it works.

    <iframe style="width: 129%; height: 350px; border: 0px none;" src="data:text/html;charset=utf-8,&lt;html&gt;&lt;body&gt;&lt;script type=&quot;text/javascript&quot; charset=&quot;utf-8&quot; src=&quot;;&gt;&lt;/script&gt;&lt;/body&gt;&lt;/html&gt;"></iframe>
  • @yariplus
    Great idea to do this with an iframe.

    The important factor to this problem is that DOM parsing/building is designed as a one-way street. The browser processes your HTML from top to bottom. To add/delete it uses a pointer, which is always at a specific point in the DOM at a time. The problem with asynchronously loaded scripts and document.write() is, that document.write() tries to put the content wherever the pointer is right now. It has no information itself where to put the content.
    In this quick example I put the pointer at the end of the page, when the script tries to execute document.write(). That's not always the case! The async loading can finish whenever, meaning that, worst case, document.write() would slap its content just somewhere on your page, leading to obvious fails. That's why the browser warns and refuses to execute document.write() at all. A way better solution than having your content appear at a different place every time you refresh the page, depending on how long the async loading took. Imagine to have to debug something like that. 😉

    The <iframe> solution works, because <iframe>s are actually their own DOM inside the DOM, including the parsing process. I can remember how we used to avoid <iframe>s; things like that brought them back into the good parts of HTML. 🙂

  • @rbeer Isn't there some kind of issue with IE and iframe data urls not being recognized as same-origin?

  • I don't know, sorry. 😟
    Actually, because I don't know anything about IE, at all. When FF gained users and Chrome came into play, I decided to abandon IE all together. Now, I know this looks like a stupid move, but around the same time also mobile devices gained market shares. Forseeing that those would be the future anyway, I diverted my focus onto them rather any longer hassling with IE.

  • @pitaj I just checked. It's actually worse than that. IE doesn't support html Data URIs whatsoever, nor the srcdoc attribute.

    So "Thanks, Microsoft!" for making this great feature completely useless.

  • So the bigger question.... is there a good way to pop dynamic content via JS into a widget?

  • @scottalanmiller Sure! My minecraft plugin does this. Using the action:widgets.loaded hook for loading the initial data and appending it via jQuery using the data-widget selector, then I update the data using websockets and/or a setTimeout with an ajax call.

Suggested Topics