How to load script in puppeteer?

Viewed 2639

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.org/get')
  await page.evaluate(async () => {
    var script = document.createElement('script');
    script.setAttribute('src','https://unpkg.com/axios@0.21.0/dist/axios.min.js');
    document.head.appendChild(script);
    var r = await axios.get('https://httpbin.org/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?

2 Answers

Use page.addScriptTag for this:

await page.goto('https://example.com');

await page.addScriptTag({ url: 'https://unpkg.com/axios@0.21.0/dist/axios.min.js' }); 

const data = await page.evaluate(async () => {
  const response = await axios.get('https://httpbin.org/get')
  return response.data; // <-- this is important: the whole response cannot be returned
});

page.addScriptTag is useful in the common 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");

let browser;
(async () => {
  browser = await puppeteer.launch({headless: true});
  const [page] = await browser.pages();
  const result = await page.evaluate(async () => {
    var script = document.createElement("script");
    const result = new Promise(resolve =>
      script.onload = () => 
        resolve(axios.get("https://httpbin.org/get"))
    );
    var url = "https://unpkg.com/axios@0.21.0/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(async () => await browser?.close())
;
Related