web-dev-qa-db-ja.com

Puppeteerでページが読み込まれる前にlocalstorageアイテムを設定しますか?

JWT_TOKENが設定されていない場合、ホームページに移動するルーティングロジックがいくつかあります...ページがロードされる前/ jsが呼び出される前にこれを設定します。

どうすればいいですか?

12
christoffee

次のようにlocalStorageアイテムを登録する必要があります:

await page.evaluate(() => {
  localStorage.setItem('token', 'example-token');
});

これは、ページpage.gotoの後に行う必要があります。ブラウザには、ローカルストレージアイテムを登録するためのURLが必要です。この後、同じページをもう一度入力します。この時間トークンは、ページがロードされる前にここにあるはずです。

以下は完全に機能する例です:

const puppeteer = require('puppeteer');
const http = require('http');

const html = `
<html>
  <body>
    <div id="element"></div>

    <script>
      document.getElementById('element').innerHTML = 
        localStorage.getItem('token') ? 'signed' : 'not signed';
    </script>
  </body>
</html>`;

http
  .createServer((req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.write(html);
    res.end();
  })
  .listen(8080);

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.goto('http://localhost:8080/');

  await page.evaluate(() => {
    localStorage.setItem('token', 'example-token');
  });

  await page.goto('http://localhost:8080/');

  const text = await page.evaluate(
    () => document.querySelector('#element').textContent
  );

  console.log(text);
  await browser.close();

  process.exit(0);
})();
15
Everettss

PuppeteerのGitHubの問題 でこれに関するいくつかの議論があります。

ドメインにページをロードし、localStorageを設定してから、localStorageを準備してロードしたい実際のページに移動できます。また、最初のURLロードをインターセプトして、実際にページをロードする代わりに即座に戻ることができるため、多くの時間を節約できる可能性があります。

const doSomePuppeteerThings = async () => {
  const url = 'http://example.com/';
  const browser = await puppeteer.launch();
  const localStorage = { storageKey: 'storageValue' };
  setDomainLocalStorage(browser, url, localStorage);

  const page = await browser.newPage();
  // do your actual puppeteer things now
};

const setDomainLocalStorage = async (browser, url, values) => {
  const page = await browser.newPage();
  await page.setRequestInterception(true);
  page.on('request', r => {
    r.respond({
      status: 200,
      contentType: 'text/plain',
      body: 'Tweak me.',
    });
  });
  await page.goto(url);
  await page.evaluate(values => {
    for (const key in values) {
      localStorage.setItem(key, values[key]);
    }
  }, values);
  await page.close();
};
3
markdon

goToを2倍にする必要がない場合、これは機能します。

const browser = await puppeteer.launch();
browser.on('targetchanged', async (target) => {
  const targetPage = await target.page();
  const client = await targetPage.target().createCDPSession();
  await client.send('Runtime.evaluate', {
    expression: `localStorage.setItem('hello', 'world')`,
  });
});
// newPage, goTo, etc...

似たようなことをする人形劇の灯台ドキュメントから適応: https://github.com/GoogleChrome/lighthouse/blob/master/docs/puppeteer.md

0
Rémi Gebski