puppeteer 中缺少请求标头

Posted

技术标签:

【中文标题】puppeteer 中缺少请求标头【英文标题】:Missing request headers in puppeteer 【发布时间】: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 的限制?

感谢您的建议!

【问题讨论】:

【参考方案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 设置为相同的行为方式?跨度>

以上是关于puppeteer 中缺少请求标头的主要内容,如果未能解决你的问题,请参考以下文章

POST请求中缺少授权标头[重复]

对 Django 的请求中缺少自定义标头

仅在 Angular 资源请求中缺少 CORS 标头

POST 请求标头中的内容类型缺少 FormData 边界

Ionic 3.5.2 http 请求中缺少授权标头

Chrome 网络检查器中缺少请求标头(和发送的 cookie)?