5

I'm not a full-time Javascript developer. We have a web app and one piece is to write out a small informational widget onto another domain. This literally is just a html table with some values written out into it. I have had to do this a couple of times over the past 8 years and I always end up doing it via a script that just document.write's out the table.

For example:

document.write('<table border="1"><tr><td>here is some content</td></tr></table>'); 

on theirdomain.com

<body> .... <script src='http://ourdomain.com/arc/v1/api/inventory/1' type='text/javascript'></script> ..... </body> 

I always think this is a bit ugly but it works fine and we always have control over the content (or a trusted representative has control such as like your current inventory or something). So another project like this came up and I coded it up in like 5 minutes using document.write. Somebody else thinks this is just too ugly but I don't see what the problem is. Re the widget aspect, I have also done iframe and jsonp implementations but iframe tends not to play well with other site's css and jsonp tends to just be too much. Is there a some security element I'm missing? Or is what I'm doing ok? What would be the strongest argument against using this technique? Is there a best practice I don't get?

8
  • performance, no-js, and seo are the main gripes. some just don't like it for what seems to be personal reasons... Commented Jan 16, 2014 at 22:01
  • 1
    It simply will crash horribly if your remote script is not synchronously loaded. Requiring that will be an issue when redesigning the including page. Commented Jan 16, 2014 at 22:03
  • 1
    @Bergi crash? or just not render? Can totally live with that too since that would be same with a jsonp or iframe sol'n Commented Jan 16, 2014 at 22:04
  • @bergi: that's true. an innerHTML option would be better, but philosophically they are the same concept. then again, by the time you hard-code an id or url into the remote script, and take care of old IE, it loses a lot of simplicity... Commented Jan 16, 2014 at 22:04
  • @dandavis thx Dan and Bergi, I should have put more of reqs. Would not want a jQuery sol'n (was thinking of doing load or something). There wouldn't be any further interaction with the dom at that point. Commented Jan 16, 2014 at 22:10

3 Answers 3

4

To be honest, I don't really see a problem. Yes, document.write is very old-school, but it is simple and universally supported; you can depend on it working the same in every browser.

For your application (writing out a HTML table with some data), I don't think a more complex solution is necessary if you're willing to assume a few small risks. Dealing with DOM mutation that works correctly across browsers is not an easy thing to get right if you're not using jQuery (et al).

The risks of document.write:

  • Your script must be loaded synchronously. This means a normal inline script tag (like you're already using). However, if someone gets clever and adds the async or defer attributes to your script tag (or does something fancy like appending a dynamically created script element to the head), your script will be loaded asynchronously.

    This means that when your script eventually loads and calls write, the main document may have already finished loading and the document is "closed". Calling write on a closed document implicitly calls open, which completely clears the DOM – it's esentially the same as wiping the page clean and starting from scratch. You don't want that.

  • Because your script is loaded synchronously, you put third-party pages at the mercy of your server. If your server goes down or gets overloaded and responds slowly, every page that contain your script tag cannot finish loading until your server does respond or the browser times out the request.

    The people who put your widget on their website will not be happy.

If you're confident in your uptime, then there's really no reason to change what you're doing.

The alternative is to load your script asynchronously and insert your table into the correct spot in the DOM. This means third parties would have to both insert a script snippet (either <script async src="..."> or use the dynamic script tag insertion trick. They would also need to carve out a special <div id="tablegoeshere"> for you to put your table into.

Sign up to request clarification or add additional context in comments.

4 Comments

thx for answer @josh3736 - re the concern about write (the second paragraph in your first bullet point). The way I have it currently constructed, would this be an issue? What if we assume our server returns in 300ms and the remainder of the page loads in 10ms (ie that the remote document.write starts 290ms after completion) - would this cause the main page to be blown away. I haven't seen this in practice but this would obviously be my largest concern.
Re second point, I agree that's a legitimate concern but would be true of any remotely loaded data or is there something specific to this implementation that makes it particuarily fragile. The script async suggestion sounds really solid. Let me look into that more - is that what you'd sugggest? I really appreciate answer.
@timpone: The whole point is that as your code is now, it is loaded and executed synchronously. The browser stops doing anything else until your script loads, so it doesn't matter if your server responds in 300ms or a full minute. Re #2, this is a property unique to the <script> tag due to legacy concerns. The original Netscape did it this way (synchronously), and browsers still do it precisely because it would break this (still common) use of document.write otherwise. If you switch to an async loading method, you simply can't use document.write.
thx for clarification. I just wanted to be sure I was understanding you correctly.
2

Using document.write() after loading the entire DOM do not allow you to access DOM any further.

See Why do I need to use document.write instead of DOM manipulation methods?.

You are in that case putting away a very powerfull functionnality of in web page...

4 Comments

This doesn't make sense. When document.write() called on an open document (one that hasn't been completely loaded yet, ie when called from a synchronous <script> as the OP is doing), it doesn't do anything to the DOM. You can still access it normally. The thread you linked to is talking about asynchronously calling document.write, which could very well happen after the document closes. In that case, the DOM is blown away.
This is effectively working on this JSFiddle (jsfiddle.net/2Z3cZ)... I always thought like it... (but not in this one : jsfiddle.net/2Z3cZ/2)
thx @cubitouch for jsfiddle - when you say access DOM, do you mean the DOM of written out html or the DOM of any of the page. Taking for example the simple table in the question; I don't want to add anything to that DOM but would I be able to do DOM manipulation on the remainder of the page?
In that case, It seems harmless. But it seems to me like a bad practice as you work with text instead of objects.
2

Is there a some security element I'm missing?

The security risk is for them in that theirdomain.com trusting your domain's script code to not do anthing malicous. Your client script will run in the context of their domain and can do what it likes such as stealing cookies or embedding a key logger (not that you would do that of course). As long as they trust you, that is fine.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.