Document: write() method
Deprecated: This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see thecompatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.
Warning:Use of thedocument.write() method is strongly discouraged.Avoid using it, and where possible replace it in existing code.
This method has very idiosyncratic behavior.In some cases, this method can affect the state of theHTML parser while the parser is running, resulting in a DOM that does not correspond to the source of the document (e.g., if the string written is the string "
<plaintext>" or "<!--").In other cases, the call can clear the current page first, as ifdocument.open()had been called.In yet more cases, the method is simply ignored, or throws an exception. Users agents areexplicitly allowed to avoid executingscriptelements inserted via this method.And to make matters even worse, the exact behavior of this method can in some cases be dependent on network latency, which can lead to failures that are very hard to debug.For all these reasons, use of this method is strongly discouraged.
Warning:This method parses its input as HTML, writing the result into the DOM.APIs like this are known asinjection sinks, and are potentially a vector forcross-site scripting (XSS) attacks, if the input originally came from an attacker.
You can mitigate this risk by always passingTrustedHTML objects instead of strings andenforcing trusted types.SeeSecurity considerations for more information.
Thewrite() method of theDocument interface writes text in one or moreTrustedHTML or string parameters to a document stream opened bydocument.open().
In this article
Syntax
write(markup)write(markup, markup2)write(markup, markup2, /* …, */ markupN)Parameters
markup, …,markupNTrustedHTMLobjects or strings containing the markup to be written to the document.
Return value
None (undefined).
Exceptions
InvalidStateErrorDOMExceptionThe method was called on an XML document, or called when the parser is currently executing a custom element constructor.
TypeErrorA string is passed as one of the parameters whenTrusted Types are enforced andno default policy has been defined for creating
TrustedHTMLobjects.
Description
document.write() parses the markup text in the objects passed as parameters into the open document's object model (DOM), in the order that the parameters are specified.
Becausedocument.write() writes to the documentstream, callingdocument.write() on a closed (loaded) document (without first callingdocument.open()) automatically callsdocument.open(), which will clear the document.
The exception is that if thedocument.write() call is embedded within an inline HTML<script> tag, then it will not automatically calldocument.open():
<script> document.write("<h1>Main title</h1>");</script>document.write() (anddocument.writeln) cannot be used with XML or XHTML, and attempting to do so will throw anInvalidStateError exception.This is the case if opening a local file with a .xhtml file extension or for any document served with anapplication/xhtml+xml MIME type.More information is available in theW3C XHTML FAQ.
Usingdocument.write() indeferred orasynchronous scripts will be ignored and you'll get a message like "A call todocument.write() from an asynchronously-loaded external script was ignored" in the error console.
In Edge only, callingdocument.write() more than once in an<iframe> causes the error "SCRIPT70: Permission denied".
Security considerations
The method is a possible vector forcross-site scripting (XSS) attacks, where potentially unsafe strings provided by a user are injected into the DOM without first being sanitized.While the method may block<script> elements from executing when they are injected in some browsers (seeIntervening against document.write() for Chrome), it is susceptible to many other ways that attackers can craft HTML to run malicious JavaScript.
You can mitigate these issues by always passingTrustedHTML objects instead of strings, andenforcing trusted types using therequire-trusted-types-for CSP directive.This ensures that the input is passed through a transformation function, which has the chance tosanitize the input to remove potentially dangerous markup (such as<script> elements and event handler attributes), before it is injected.
Examples
>Writing TrustedHTML
This example uses theTrusted Types API to sanitize HTML strings of<script> elements before they are written to a document.
The example initially displays some default text and a button.When the button is clicked, the current document is opened, three strings of HTML are converted toTrustedHTML instances and written into the document, and the document is then closed.This replaces the document in the example frame, including the original HTML for the button and the JavaScript that made the update!
HTML
<p>Some original document content.</p><button type="button">Replace document content</button>JavaScript
First we use theWindow.trustedTypes property to access the globalTrustedTypePolicyFactory, and use itscreatePolicy() method to define a policy called"docPolicy".
The new policy defines a transformation functioncreateHTML() for creating theTrustedHTML objects that we will pass to thewrite() method.This method can do anything it likes with the input string: the trusted types API just requires that you pass the input through a policy transformation function, not that the transformation function does anything in particular.
You'd use the method tosanitize the input by removing potentially unsafe features such as<script> tags or event handler attributes.Sanitization is hard to get right, so this process typically uses a reputable third-party library such asDOMPurify.
For the purposes of demonstration, here we implement a rudimentary "sanitizer" that replaces< symbols in script opening and closing tags with the< character.
const policy = trustedTypes.createPolicy("docPolicy", { createHTML(string) { return string .replace("<script", "<script") .replace("</script", "</script"); },});We can then use theTrustedTypePolicy.createHTML() method on the returned policy to createTrustedHTML objects from our original input strings.These are then passed to thewrite() function when the user clicks the button.
const oneInput = "<h1>Out with the old</h1>";const twoInput = "<p>in with the new!</p>";const threeInput = "<script>alert('evil afoot')<" + "/script>";const replace = document.querySelector("#replace");replace.addEventListener("click", () => { document.open(); document.write( policy.createHTML(oneInput), policy.createHTML(twoInput), policy.createHTML(threeInput), ); document.close();});Results
Press the button and note that the HTML elements that we trust (in this example) are injected, but the untrusted<script> element is now rendered as plain text.
Writing strings
This is the same as the preceding example, except that trusted types are not used or enforced.We're writing unsanitized strings, which may provide a path forXSS attacks.
The example initially displays some default text and a button.When the button is clicked, the current document is opened, three strings of HTML are written into the document, and the document is then closed.This replaces the document in the example frame, including the original HTML for the button and the JavaScript that made the update.
HTML
<p>Some original document content.</p><button type="button">Replace document content</button>JavaScript
const replace = document.querySelector("#replace");const oneInput = "<h1>Out with the old</h1>";const twoInput = "<p>in with the new!</p>";const threeInput = "<script>alert('evil afoot')<" + "/script>";replace.addEventListener("click", () => { document.open(); document.write(oneInput, twoInput, threeInput); document.close();});Results
Press the button and note that all the HTML elements are injected.This includes the<script> element, which in a real application might have executed harmful code.
Specifications
| Specification |
|---|
| HTML> # dom-document-write-dev> |