【问题标题】:Missing request headers in puppeteerpuppeteer 中缺少请求标头
【发布时间】:2018-04-15 04:12:28
【问题描述】:

我想在使用 puppeteer 编写的测试期间读取请求 cookie。但我注意到我检查的大多数请求只有引用者和用户代理标头。如果我在 Chrome 开发工具中查看相同的请求,它们会有更多的标头,包括 Cookie。要查看它,请将下面的代码复制粘贴到https://try-puppeteer.appspot.com/

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

page.on('request', function(request) {
  console.log(JSON.stringify(request.headers, null, 2));
});

await page.goto('https://google.com/', {waitUntil: 'networkidle'});

await browser.close();

对于可以访问和不能访问的请求标头是否有限制?是 Chrome 本身的限制还是 puppeteer 的限制?

感谢您的建议!

【问题讨论】:

    标签: cookies http-headers request-headers puppeteer


    【解决方案1】:

    我在尝试使用 Puppeteer 测试某些 CORS 行为时也看到了这一点 - 我发现某些请求中缺少 Origin 标头。

    查看我发现的 GitHub 问题 an issue,其中提到 Puppeteer 不侦听底层 Chrome DevTools 协议的 Network.responseReceivedExtraInfo 事件,此事件提供了 Network.responseReceived 事件不可用的额外响应标头。还有一个类似的Network.requestWillBeSentExtraInfo 请求事件。

    连接到这些事件似乎让我得到了我需要的所有标题。下面是一些示例代码,它从所有这些事件中捕获数据并将其合并到由请求 ID 键入的单个对象中:

    // Setup.
    const browser = await puppeteer.launch()
    const page = await browser.newPage()
    const cdpRequestDataRaw = await setupLoggingOfAllNetworkData(page)
    
    // Make requests.
    await page.goto('http://google.com/')
    
    // Log captured request data.
    console.log(JSON.stringify(cdpRequestDataRaw, null, 2))
    
    await browser.close()
    
    // Returns map of request ID to raw CDP request data. This will be populated as requests are made.
    async function setupLoggingOfAllNetworkData(page) {
        const cdpSession = await page.target().createCDPSession()
        await cdpSession.send('Network.enable')
        const cdpRequestDataRaw = {}
        const addCDPRequestDataListener = (eventName) => {
            cdpSession.on(eventName, request => {
                cdpRequestDataRaw[request.requestId] = cdpRequestDataRaw[request.requestId] || {}
                Object.assign(cdpRequestDataRaw[request.requestId], { [eventName]: request })
            })
        }
        addCDPRequestDataListener('Network.requestWillBeSent')
        addCDPRequestDataListener('Network.requestWillBeSentExtraInfo')
        addCDPRequestDataListener('Network.responseReceived')
        addCDPRequestDataListener('Network.responseReceivedExtraInfo')
        return cdpRequestDataRaw
    }
    

    【讨论】:

      【解决方案2】:

      那是因为您的浏览器会根据设置和功能设置一堆标题,并且还包括例如它为特定页面在本地存储的 cookie。

      如果要添加额外的header,可以使用如下方法:

      page.setExtraHTTPHeadersdocs here.

      page.setUserAgentdocs here.

      page.setCookiesdocs here.

      通过这些,您可以模仿您看到 Chrome 浏览器调度的额外标头。

      【讨论】:

      • 重点是测试浏览器是否可以在另一个响应中添加cookies。如果我手动添加标头,我只会测试我是否手动添加它们)我可以在手动测试期间看到它们添加到普通 Chrome 中的请求标头,但也许有一种方法可以将无头 Chrome 设置为相同的行为方式?跨度>
      猜你喜欢
      • 2018-04-06
      • 2018-10-31
      • 1970-01-01
      • 1970-01-01
      • 2019-06-23
      • 2015-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多