Puppeteer执行代码报错:Protocol error (Runtime.callFunctionOn): Target closed
Fixing the "Target closed" Error in Your Puppeteer + OpenAjax Script
Hey there! Let's break down what's causing that "Target closed" error and fix your script step by step. I see you're new to Puppeteer, so I'll explain each change clearly.
Key Issues in Your Original Code
- You're closing the browser too early:
page.evaluate()returns a Promise, but you aren't waiting for it to finish before callingbrowser.close(). This means the browser shuts down while your accessibility evaluation is still running, triggering the "Target closed" error. - No error handling: You don't have a
try/catchblock, so any uncaught errors (like missing dependencies) turn into unhandled promise rejections. - OpenAjax isn't available in the browser context: Your Node.js code requires
oaa_a11y_evaluation.js, but Puppeteer's browser environment is completely separate from Node. The browser has no idea whatOpenAjaxis, which is causing silent failures that lead to the target closing.
Fixed Code with Explanations
Here's the revised script with all necessary fixes:
'use strict'; const puppeteer = require('puppeteer'); async function evaluateRules() { // Now OpenAjax will be available thanks to the script injection below const ruleset = OpenAjax.a11y.RulesetManager.getRuleset("ARIA_STRICT"); const evaluatorFactory = OpenAjax.a11y.EvaluatorFactory.newInstance(); evaluatorFactory.setParameter('ruleset', ruleset); evaluatorFactory.setFeature('eventProcessing', 'fae-util'); evaluatorFactory.setFeature('groups', 7); const evaluator = evaluatorFactory.newEvaluator(); const evaluation = evaluator.evaluate(window.document, document.title, document.location.href); // Return the JSON result so we can log it in Node.js return evaluation.toJSON(true); } (async() => { const browser = await puppeteer.launch(); try { const page = await browser.newPage(); // Inject the OpenAjax library into the browser (critical fix!) await page.addScriptTag({ path: './oaa_a11y_evaluation.js' }); // Use networkidle2 instead of load to ensure page is fully ready await page.goto('http://mihirkumar.com/', { waitUntil: 'networkidle2' }); // Wait for the evaluation to finish before proceeding const evaluationResult = await page.evaluate(evaluateRules); console.log('Accessibility Evaluation Result:', evaluationResult); } catch (error) { // Catch and log any errors so you can debug easily console.error('Something went wrong:', error); } finally { // Always close the browser, even if an error occurs await browser.close(); } })();
What Changed & Why
- Added
awaittopage.evaluate(): This ensures we wait for the accessibility evaluation to complete before closing the browser. - Added
try/catch/finally: Thetryblock runs your main logic,catchcaptures any errors (so you can see exactly what's breaking), andfinallyguarantees the browser closes even if something fails. - Injected OpenAjax with
page.addScriptTag(): This loads the accessibility library directly into the browser's context, makingOpenAjaxavailable to yourevaluateRulesfunction. - Switched to
networkidle2: This waits until there are no more than 2 network connections for 500ms, which is more reliable thanloadfor pages with dynamic content. - Returned the evaluation result: Now you can see the output of your accessibility check in the Node.js console.
Extra Troubleshooting Tips
- If you still get errors about
OpenAjaxnot being defined, double-check thatoaa_a11y_evaluation.jscorrectly exposes theOpenAjaxglobal object. Some libraries need initialization steps—check the library's docs if needed. - For pages with heavy dynamic content, add a small wait after
page.goto()withawait page.waitForTimeout(1000)(adjust the time as needed) to ensure all elements are rendered before running the evaluation.
内容的提问来源于stack exchange,提问作者Mihir Kumar
相关产品推荐
相关产品推荐

