Puppeteer/NodeJS点击提交时追加FormData键值对及拦截卡顿问题咨询
问题解答
一、现有实现的正确性分析与方案选择
你的现有实现存在明显问题,不会正常生效,且不会出现你担心的「原生表单数据覆盖你设置的内容」的情况,反而会直接丢失所有原生表单数据,原因如下:
- 你用
page.once注册的请求监听会在page.goto发起的第一个页面请求触发,根本等不到点击提交的表单POST请求 - 直接将Node端
form-data实例赋值给interceptedRequest.postData不符合Puppeteer的接口要求,postData需要传入序列化后的字符串,而非FormData实例 - 你没有读取原请求携带的表单数据,直接替换成了只包含
newvalue的内容,原生填写的所有表单字段都会丢失
两种可行方案如下:
方案1:请求拦截修正版
仅当你无法通过前端注入(比如表单提交是前端JS异步发的,没有对应表单DOM)的场景下使用,写法如下:
// 先开启请求拦截 await page.setRequestInterception(true); // 注册请求监听,用on而非once,匹配目标提交请求 const handleRequest = (interceptedRequest) => { // 匹配条件根据你的实际场景调整,比如匹配提交接口路径、请求方法为POST if (interceptedRequest.method() === 'POST' && interceptedRequest.url().includes('/你的提交接口路径')) { // 拿到原表单数据 const originalPostData = interceptedRequest.postData(); let newPostData; // 处理urlencoded类型的表单 if (interceptedRequest.headers()['content-type']?.includes('application/x-www-form-urlencoded')) { const params = new URLSearchParams(originalPostData); params.append('newvalue', 'some new value'); newPostData = params.toString(); } // 处理multipart/form-data类型的表单(如果是这种类型建议直接用方案2更简单) else { // multipart类型解析相对复杂,需要自行解析原postData后追加字段再序列化 } // 传递修改后的postData interceptedRequest.continue({ postData: newPostData, headers: { ...interceptedRequest.headers(), // 如果是urlencoded不需要改content-length,Puppeteer会自动处理 } }); // 处理完后移除监听,避免影响其他请求 page.off('request', handleRequest); return; } // 其他请求正常放行 interceptedRequest.continue(); }; page.on('request', handleRequest); // 之后再执行点击提交的逻辑 await page.click('#submit');
方案2:浏览器端注入隐藏字段(优先推荐)
不需要处理复杂的请求拦截,兼容性最好,不会出现请求异常问题:
// 填写完表单后,点击提交前执行注入 await page.evaluate(() => { // 替换为你实际的表单选择器 const targetForm = document.querySelector('#formId'); const hiddenInput = document.createElement('input'); hiddenInput.type = 'hidden'; hiddenInput.name = 'newvalue'; hiddenInput.value = 'some new value'; targetForm.appendChild(hiddenInput); }); // 直接点击提交即可,原生表单会自动携带新增的字段 await page.click('#submit');
二、page.goto无限卡顿的原因
卡顿的直接原因就是你在goto之前注册了page.once('request')监听,goto发起的第一个GET页面请求直接触发了你的监听逻辑,你把这个GET请求篡改成了POST请求,还传入了格式错误的postData,服务端无法返回正常的页面内容,同时Puppeteer也因为请求格式异常无法正常加载页面,所以会一直卡住。
只需要把请求监听的注册逻辑移到点击提交之前,或者直接用方案2的注入方式,即可解决卡顿问题。
内容的提问来源于stack exchange,提问作者KarlB25
相关产品推荐
相关产品推荐

