Puppeteer使用page.setContent()时Cookies无法正常工作
问题原因
当使用page.setContent()直接加载本地HTML内容时,页面的源(origin)为null(或属于无有效域名的本地文件协议环境)。浏览器的同源策略限制了在这种无有效源的情况下读取document.cookie,因为Cookie必须绑定到具体的域名/源才能正常工作。
解决方案
方案1:先导航到空白页面再设置内容
先通过page.goto('about:blank')让页面拥有一个有效的源(about:blank的源),再调用page.setContent()加载内容,此时即可正常访问document.cookie。
修改后的代码:
const path = require('path'); const fs = require('fs'); const puppeteer = require('puppeteer'); (async () => { var filePath = path.join(__dirname, '../assets/index.html') var contentHtml = fs.readFileSync(filePath, 'utf8'); const browser = await puppeteer.launch({ headless: "new", }); const page = await browser.newPage(); await page.setJavaScriptEnabled(true); page.on('console', msg => console.log('PAGE LOG:', msg.text())); // 先导航到空白页面,赋予页面有效源 await page.goto('about:blank'); await page.setContent(contentHtml); await page.evaluate(async () => { console.log(`cookies`, document.cookie); // 现在可以正常执行 }); await browser.close(); })();
方案2:给page.setContent()指定baseURL参数
在调用page.setContent()时,通过baseURL参数为页面指定一个有效的源(比如http://localhost),浏览器会将这个URL当作页面的源,从而允许访问Cookie。
修改后的代码:
const path = require('path'); const fs = require('fs'); const puppeteer = require('puppeteer'); (async () => { var filePath = path.join(__dirname, '../assets/index.html') var contentHtml = fs.readFileSync(filePath, 'utf8'); const browser = await puppeteer.launch({ headless: "new", }); const page = await browser.newPage(); await page.setJavaScriptEnabled(true); page.on('console', msg => console.log('PAGE LOG:', msg.text())); // 指定baseURL,赋予页面有效源 await page.setContent(contentHtml, { baseURL: 'http://localhost' }); await page.evaluate(async () => { console.log(`cookies`, document.cookie); // 现在可以正常执行 }); await browser.close(); })();
补充说明
如果需要设置Cookie后再读取,确保设置Cookie时的domain或url参数与你指定的源匹配(比如方案2中的http://localhost),否则Cookie不会被绑定到当前页面的源上,依然无法读取。
内容的提问来源于stack exchange,提问作者Justin Fiedler
相关产品推荐
相关产品推荐

