From 588c6f95d0549e95ca89a0cb4ec74d2175af7d54 Mon Sep 17 00:00:00 2001 From: Daniel Kaplan Date: Thu, 28 Dec 2023 04:56:58 -0800 Subject: [PATCH] Change "Executing scripts" examples * For each example, the HTML is exactly the same, allowing the reader to focus on what matters: the effect of different runScripts values. * When a script is a no-op, 0 is logged instead of 1. * The examples can be copied and pasted elsewhere and, without modification, output useful information via the console. --- README.md | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ed69daffe..f12c06e6a 100644 --- a/README.md +++ b/README.md @@ -65,22 +65,24 @@ However, this is also highly dangerous when dealing with untrusted content. The ```js const dom = new JSDOM(` - +
+ `); // The script will not be executed, by default: -dom.window.document.body.children.length === 1; +console.log(dom.window.document.getElementById("content").children.length); // 0 ``` To enable executing scripts inside the page, you can use the `runScripts: "dangerously"` option: ```js const dom = new JSDOM(` - +
+ `, { runScripts: "dangerously" }); // The script will be executed and modify the DOM: -dom.window.document.body.children.length === 2; +console.log(dom.window.document.getElementById("content").children.length); // 1 ``` Again we emphasize to only use this when feeding jsdom code you know is safe. If you use it on arbitrary user-supplied code, or code from the Internet, you are effectively running untrusted Node.js code, and your machine could be compromised. @@ -92,15 +94,22 @@ Event handler attributes, like `
`, are also governed by this set If you are simply trying to execute script "from the outside", instead of letting ` +`, { runScripts: "outside-only" }); + +// run a script outside of JSDOM: +dom.window.eval('document.getElementById("content").append(document.createElement("p"));'); -window.eval(`document.body.innerHTML = "

Hello, world!

";`); -window.document.body.children.length === 1; +console.log(dom.window.document.getElementById("content").children.length); // 1 +console.log(dom.window.document.getElementsByTagName("hr").length); // 0 +console.log(dom.window.document.getElementsByTagName("p").length); // 1 ``` This is turned off by default for performance reasons, but is safe to enable. -(Note that in the default configuration, without setting `runScripts`, the values of `window.Array`, `window.eval`, etc. will be the same as those provided by the outer Node.js environment. That is, `window.eval === eval` will hold, so `window.eval` will not run scripts in a useful way.) +Note that in the default configuration, without setting `runScripts`, the values of `window.Array`, `window.eval`, etc. will be the same as those provided by the outer Node.js environment. That is, `window.eval === eval` will hold, so `window.eval` will not run scripts in a useful way. We strongly advise against trying to "execute scripts" by mashing together the jsdom and Node global environments (e.g. by doing `global.window = dom.window`), and then executing scripts or test code inside the Node global environment. Instead, you should treat jsdom like you would a browser, and run all scripts and tests that need access to a DOM inside the jsdom environment, using `window.eval` or `runScripts: "dangerously"`. This might require, for example, creating a browserify bundle to execute as a `