为何Puppeteer的evaluate未触发CORS错误?需验证同源策略生效
Puppeteer中CORS策略未触发错误的原因及解决方法
核心问题分析
你遇到的情况主要有两个关键原因:
1. 手动设置Origin请求头无效
浏览器出于安全限制,不允许网页脚本手动修改Origin请求头。你在fetch配置中添加的headers: {Origin:myOrigin}会被浏览器自动忽略,实际发送的请求的Origin头由当前页面的源(即https://example.com)自动生成。
2. 未正确捕获异步Promise错误
fetch的CORS错误属于异步Promise拒绝,不会触发page.on("pageerror")事件(该事件仅捕获页面中的未处理同步错误)。同时你在page.evaluate内部的代码没有对fetch的Promise进行错误捕获,导致错误被静默处理,没有传递到Node.js环境的控制台。
修正后的代码
要正确触发并捕获CORS错误,需要在evaluate内部添加错误捕获,并监听页面的未处理Promise拒绝事件:
import puppeteer from 'puppeteer'; (async () => { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); await page.goto('https://example.com'); // 监听页面未处理的Promise拒绝 page.on("unhandledrejection", (reason) => { console.log("Unhandled Rejection: " + reason.toString()); }); page.on("pageerror", function(err) { console.log("Page error: " + err.toString()); }); page.on("error", function (err) { console.log("Error: " + err.toString()); }); await page.evaluate(async (otherSiteURL) => { try { console.log('当前页面源: ', window.location.origin); console.log('请求目标URL: ', otherSiteURL); let r = await fetch(otherSiteURL, {mode:'cors', method:"GET"}); // 若CORS拦截,fetch的Promise会直接reject,不会执行到此处 let data = await r.json(); console.log('响应内容: ', JSON.stringify(data)); } catch (err) { console.log('捕获到CORS错误: ', err.toString()); throw err; // 抛出错误让外部监听捕获 } }, 'https://some-other-site.com'); await browser.close(); })();
额外验证步骤
- 确认你的
some-other-site服务器确实没有返回包含https://example.com或*的Access-Control-Allow-Origin响应头,可以通过浏览器开发者工具的网络面板查看请求的响应头。 - 运行修正后的代码,此时应该能在Node.js控制台看到对应的CORS错误日志,页面控制台也会输出错误信息。
内容的提问来源于stack exchange,提问作者Mercury
相关产品推荐
相关产品推荐

