Я пытаюсь загрузить axios в хром с помощью puppeteer, код выглядит следующим образом:
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/[email protected]/dist/axios.min.js');
document.head.appendChild(script);
var r = await axios.get('https://httpbin.org/get')
console.info(r)
})
})()
Но когда я пытаюсь выполнить axios.get
, он возвращает Evaluation failed: ReferenceError: axios is not defined
. В чем проблема?
🤔 А знаете ли вы, что...
С JavaScript можно создавать расширения для различных платформ, таких как Adobe Acrobat и Microsoft Office.
Используйте для этого page.addScriptTag:
await page.goto('https://example.com');
await page.addScriptTag({ url: 'https://unpkg.com/[email protected]/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 полезен в общем случае, но если у вас есть причина сделать это вручную в контексте браузера, когда пытается OP, недостающая часть устанавливает функцию script.onload
только для запуска кода из скрипта (например, axios.get
) после того, как он загружен.
Если вы хотите вернуть данные из функции onload
обратно в Node, вы можете использовать обещание следующим образом:
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/[email protected]/dist/axios.min.js";
script.setAttribute("src", url);
document.head.appendChild(script);
return (await result).data;
});
console.info(result);
})()
.catch(err => console.error(err))
.finally(async () => await browser?.close())
;
В моем случае я пытался загрузить локальный скрипт перед загрузкой локального HTML-шаблона.
Я не хотел встраивать код скрипта в HTML-шаблон, так как HTML-шаблон уже был слишком большим.
Следующий код и локальный файл js с кодом скрипта (scriptCode.js
) находились в одном каталоге (отсюда и использование __dirname
):
const path = require("path");
// ...
const page = await browser.newPage();
await page.addScriptTag({path: path.join(__dirname, 'scriptCode.js')})
await page.setContent(html);
Если у вас есть axios в локальной папке, вы должны указать путь, по которому вы его скачали.
Но если вы все еще хотите каждый раз загружать его с CDN, вместо использования опции path
, ответ, предоставленный Vaviloff, является идеальным.
Документация: