I made a script using chrome-launcher and chrome-remote-interface to save a webpage to pdf using Chrome.
It works without any issue on my Windows machine, but when I try it on CentOS 7, I obtain the following error and I can’t figure out why. Both use Chrome v86.
On Windows I use NodeJS v12.18.4 On Linux I tried both v15.1 and v12.19
SELinux status: disabled
I tried to check if other applications were using the port in the error and there weren’t any.
node:internal/process/promises:218 triggerUncaughtException(err, true /* fromPromise */); ^ Error: connect ECONNREFUSED 127.0.0.1:43265 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1128:16) { errno: -111, code: 'ECONNREFUSED', syscall: 'connect', address: '127.0.0.1', port: 43265 }
My code:
const chromeLauncher = require('chrome-launcher'); const CDP = require('chrome-remote-interface'); const file = require('fs'); var check = 1; (async function() { async function launchChrome() { return await chromeLauncher.launch({ chromeFlags: [ '--no-first-run', '--headless', '--disable-gpu' ] }); } const chrome = await launchChrome(); const protocol = await CDP({ port: chrome.port }); const { DOM, Page, Emulation, Runtime } = protocol; await Promise.all([ Page.enable(), Runtime.enable(), DOM.enable() ]); const { frameId } = await Page.navigate({ url: 'https://url/' }); await Page.loadEventFired(); const script1 = "window.status"; while (check) { var result = await Runtime.evaluate({ expression: script1 }); if (result.result.value == 'ready_to_print') { check = 0; } } let { data } = await Page.printToPDF({ landscape: false, printBackground: true, scale: 0.7 }); file.writeFile('print.pdf', Buffer.from(data, 'base64'), 'base64', function(err) { if (err) { console.log(err); } protocol.close(); chrome.kill(); }); })();
If you have alternative ways using Chrome and scaling to 0.7, let me know.
Thanks
Advertisement
Answer
I tried to use the launchChrome() function by itself and found that it was the issue. After some research I found the solution. I had to add ‘–no-sandbox’ in the chromeLauncher.launch flags.
Here the fully working code:
const chromeLauncher = require('chrome-launcher'); const CDP = require('chrome-remote-interface'); const file = require('fs'); var check = 1; (async function() { async function launchChrome() { return await chromeLauncher.launch({ chromeFlags: [ '--no-first-run', '--headless', '--disable-gpu', '--no-sandbox' ] }); } const chrome = await launchChrome(); const protocol = await CDP({ port: chrome.port }); const { DOM, Page, Emulation, Runtime } = protocol; await Promise.all([ Page.enable(), Runtime.enable(), DOM.enable() ]); const { frameId } = await Page.navigate({ url: 'https://url/' }); await Page.loadEventFired(); const script1 = "window.status"; while(check){ var result = await Runtime.evaluate({ expression: script1 }); if(result.result.value=='ready_to_print'){ check = 0; } } let { data } = await Page.printToPDF({ landscape: false, printBackground: true, scale: 0.7 }); file.writeFile('print.pdf', Buffer.from(data, 'base64'), 'base64', function(err) { if (err) { console.log(err); } protocol.close(); chrome.kill(); }); })();