jsdom kann Skripte ausführen, die innerhalb des <head>
-Tags des Dokuments eingebettet sind, aber wie bringen Sie es dazu, Skripte auszuführen, die im Dokumentkopf über <script src="">
verknüpft sind?
Für Optionen verwende ich:
{
url: url,
resources: 'usable',
runScripts: 'dangerously',
}
// index.js
const request = require('request')
const jsdom = require('jsdom')
const {JSDOM} = jsdom
const url = 'http://localhost:8000'
request(url, (error, response, body) => {
const options = {
url: url,
resources: 'usable',
runScripts: 'dangerously',
}
const dom = new JSDOM(body, options)
console.log(dom.window.document.body.children.length) // Expecting to see `1`
console.log(dom.window.document.body.innerHTML) // Expecting to see `<h1>Hello world</h1>`
})
// external.js
document.addEventListener('DOMContentLoaded', () => {
document.write('<h1>Hello world!</h1>')
})
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSDOM test</title>
<script src="external.js"></script>
</head>
<body>
</body>
</html>
Vollständiges Mindestarbeitsbeispiel: https://github.com/cg433n/jsdom-test
Das Problem hier ist, dass DOMContentLoaded
ein asynchrones Ereignis ist. Du loggst dich ein, bevor es passieren kann. Sie müssen warten, bis es feuert; nur dann wird Ihr document.write()
passieren.
So etwas sollte wahrscheinlich funktionieren:
const dom = new JSDOM(body, options)
dom.window.document.addEventListener('DOMContentLoaded', () => {
// We need to delay one extra turn because we are the first DOMContentLoaded listener,
// but we want to execute this code only after the second DOMContentLoaded listener
// (added by external.js) fires.
setImmediate(() => {
console.log(dom.window.document.body.children.length) // Expecting to see `1`
console.log(dom.window.document.body.innerHTML) // Expecting to see `<h1>Hello world</h1>`
});
});
Ich verstehe! Ihr seid fantastisch – macht weiter so!
Hinweis: 2 Funktionen der obigen Demo sind riskant.
request
wird abgeschrieben. npm install request
ergibt:setImmediate
ist auf lange Sicht riskant .Alternativ empfehle ich die Verwendung fs
zum Lesen und Laden der js-Codes aus Dateien, siehe Stackoverflow basierend auf @EricRicketts ' FS.read()
-Ansatz in #3023 und @Domenics addEventListener()
in #1914. Die von mir vorgeschlagene Arbeitsdemo beinhaltet:
fs.readFileSync
, um externe js als Zeichenfolgen in HTML zu ladenDies wird Sie wahrscheinlich daran hindern, xhr / API-Aufrufe durchzuführen, und das Problem daher nur teilweise lösen.
Ich konnte nicht herausfinden, wie ich URLs zum Laufen bekomme.
Im Idealfall wäre ein aktualisiertes minimales JSDOM, das externe.js-Dateien über eine funktionierende URL-Demo lädt , willkommen. :Herz:
Hilfreichster Kommentar
Das Problem hier ist, dass
DOMContentLoaded
ein asynchrones Ereignis ist. Du loggst dich ein, bevor es passieren kann. Sie müssen warten, bis es feuert; nur dann wird Ihrdocument.write()
passieren.So etwas sollte wahrscheinlich funktionieren: