I'm trying to load axios in chromium using puppeteer, the code is as follows:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({headless:false})
const page = await browser.newPage()
await page.goto('')
await page.evaluate(async () => {
var script = document.createElement('script');
script.setAttribute('src','/[email protected]/dist/axios.min.js');
document.head.appendChild(script);
var r = await axios.get('')
console.log(r)
})
})()
But when I try to execute axios.get
it returns Evaluation failed: ReferenceError: axios is not defined
. What's the issue here?
I'm trying to load axios in chromium using puppeteer, the code is as follows:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({headless:false})
const page = await browser.newPage()
await page.goto('https://httpbin/get')
await page.evaluate(async () => {
var script = document.createElement('script');
script.setAttribute('src','https://unpkg./[email protected]/dist/axios.min.js');
document.head.appendChild(script);
var r = await axios.get('https://httpbin/get')
console.log(r)
})
})()
But when I try to execute axios.get
it returns Evaluation failed: ReferenceError: axios is not defined
. What's the issue here?
3 Answers
Reset to default 8Use page.addScriptTag for this:
await page.goto('https://example.');
await page.addScriptTag({ url: 'https://unpkg./[email protected]/dist/axios.min.js' });
const data = await page.evaluate(async () => {
const response = await axios.get('https://httpbin/get')
return response.data; // <-- this is important: the whole response cannot be returned
});
In my case, I was trying to load a local script before loading a local HTML template.
I did not want to embed the script code into the HTML template since the HTML template was already too big.
The following code and the local js file with the script code (scriptCode.js
) were in the same directory (hence the use of __dirname
):
const path = require("path");
// ...
const page = await browser.newPage();
await page.addScriptTag({path: path.join(__dirname, 'scriptCode.js')})
await page.setContent(html);
If you have axios in a local folder, you have to point to the path where you've downloaded it.
But if you still want to download it off its CDN every time, instead of using the path
option, the answer provided by Vaviloff is the perfect one.
Documentation:
- Page.addScriptTag
- FrameAddScriptTagOptions interface
page.addScriptTag
is useful in the mon case, but if you have reason to do this manually in the browser context as OP is attempting, the missing piece is setting a script.onload
function to only run code from the script (like axios.get
) after it's loaded.
If you want to return data from the onload
function back to Node, then you can use a promise as follows:
const puppeteer = require("puppeteer"); // ^23.6.0
let browser;
(async () => {
browser = await puppeteer.launch();
const [page] = await browser.pages();
const result = await page.evaluate(async () => {
const script = document.createElement("script");
const result = new Promise(resolve =>
script.onload = () =>
resolve(axios.get("https://httpbin/get"))
);
const url = "https://unpkg./[email protected]/dist/axios.min.js";
script.setAttribute("src", url);
document.head.appendChild(script);
return (await result).data;
});
console.log(result);
})()
.catch(err => console.error(err))
.finally(() => browser?.close());