首页 > 解决方案 > Puppeteer 在使用拦截的请求实现 request.respond 时挂起

问题描述

我正在尝试通过 Puppeteer 中的客户端身份验证。我正在尝试实施https://github.com/puppeteer/puppeteer/issues/1319#issuecomment-371503788中提出的解决方案。

我不得不稍微修改解决方案 - 使用got而不是request.

当它运行时,虽然我发现浏览器只是挂起。最终退出错误:

(node:16672) UnhandledPromiseRejectionWarning: TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at Object.main (/Users/boyded01/workspace/watson/lib/debug.js:138:22)
(node:16672) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:16672) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

我的功能是:

async function checkPage(parsedUrl, config, number, total) {

  const browser = await puppeteer.launch({
    headless: false,
    executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
  });

  const page = await browser.newPage();

  // Enable Request Interception
  await page.setRequestInterception(true);

  page.on('request', interceptedRequest => {
    // Intercept Request, pull out request options, add in client cert
    const options = {
      url: interceptedRequest.url(),
      method: interceptedRequest.method(),
      headers: interceptedRequest.headers(),
      https: {
        certificateAuthority: fs.readFileSync('/Users/------/Downloads/cloud-ca.pem'),
        certificate: fs.readFileSync('/Users/------/certs/client.crt'),
        key: fs.readFileSync('/Users/------/certs/client.key')
      }
    };

    // Fire off the request manually
    got(options, function(err, resp, body) {
      // Abort interceptedRequest on error
      if (err) {
          console.error(`Unable to call ${options.url}`, err);
          return interceptedRequest.abort('connectionrefused');
      }

      // Return retrieved response to interceptedRequest
      interceptedRequest.respond({
          status: resp.statusCode,
          contentType: resp.headers['content-type'],
          headers: resp.headers,
          body: body
      });
    });
  });

  await page
    .goto(parsedUrl.toString())
    .catch(error => console.log(chalk.red(`Error loading page: ${error.message}`)));

  await browser.close();
}

感谢您在此处提供任何帮助以使其正常工作。该解决方案非常先进,我正在努力弄清楚我在这里做错了什么。

标签: puppeteer

解决方案


我意识到我没有正确使用 got。

      const resp = await got(options)

      // Return retrieved response to interceptedRequest
      interceptedRequest.respond({
          status: resp.statusCode,
          contentType: 'text/html;charset=utf-8',
          headers: resp.headers,
          body: resp.body
      });
    }

是应该的样子。


推荐阅读