使用Puppeteer将数据对象注入窗口

时间:2019-05-25 23:38:42

标签: javascript node.js puppeteer

背景

我正在使用Puppeteer创建一些PDF。当Puppeteer加载时,我需要向页面中注入一些数据。

问题

我尝试使用evaluateOnNewDocument(),但仅使用String时成功。当我尝试使用Object时,它会失败。我也尝试过evaluate(),无论我通过什么,它都会失败。

示例

// Works
    await page.evaluateOnNewDocument(() => {
           window.pdfData = {};
           window.pdfData = "Some String";
    });

// Does not work 
    await page.evaluateOnNewDocument(() => {
           window.pdfData = {};
           window.pdfData = data;
    });

// Fails
await page.evaluate(data => {
     window.pdfData = {};
     window.pdfData = data;
}, data);

我想这样访问该对象

const data = window.pdfData;

问题

将数据对象传递到已加载的Puppeteer页面上的窗口中以便可以在页面内访问以使用数据客户端的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

将对象传递给EvaluationOnNewDocument

evaluateOnNewDocument与评估类似,可以将数据传递给它并在内部读取。只要有新窗口/导航/框架,它就会运行。

await page.evaluateOnNewDocument(data => {
  window.pdfData = data;
}, data);

循环JSON

您传递给evaluateevaluateOnNewDocument的任何对象都将被序列化,这意味着如果它是循环JSON,则可能无法按预期工作。

但是,如果它不是循环的json,那么它将起作用。考虑下面的示例,

const data = {
  bar: "foo"
};

await page.evaluateOnNewDocument(data => {
  window.pdfData = data;
}, data);

await page.goto("http://example.com");
const result = await page.evaluate(() => window.pdfData);

结果将为{bar: 'foo'}

但是只是将示例更改为这样,

const data = {
  bar: "foo"
};

data._self = data; // reference to itself somehow.

这将导致此错误,

(node:13389) UnhandledPromiseRejectionWarning: TypeError: Converting circular structure to JSON
    at JSON.stringify (<anonymous>)
    at serializeArgument (node_modules/puppeteer/lib/helper.js:40:19)
    at Array.map (<anonymous>)
    at Function.evaluationString (node_modules/puppeteer/lib/helper.js:31:29)
    at Page.evaluateOnNewDocument (node_modules/puppeteer/lib/Page.js:790:27)
    at Page.<anonymous> (node_modules/puppeteer/lib/helper.js:111:23)

如果您有循环JSON,请确保删除引用。

有大量的库,例如:flattedfclonesafe-clone-deep

我将使用fclone

const fclone = require("fclone");

// ... other code

await page.evaluateOnNewDocument(data => {
    window.pdfData = data;
}, fclone(data));

// ... other code

console.log(result);

输出将变为

{ _self: '[Circular]', bar: 'foo' }