如何在Chromium浏览器控制台中同步提取Fetch请求的待发送头信息(无需等待请求执行)
嘿,我来帮你解决这个同步提取Fetch头的问题!根据你的需求——要同步获取头信息、不用实际发送请求、还得能被DrissionPage的run_js直接返回结果——其实浏览器原生的Request API就能完美搞定,完全不需要异步操作或者轮询。
核心思路:用Request API同步构造请求对象
浏览器的Request构造函数是同步操作,它会模拟出你要发送的Fetch请求的所有细节:包括自动填充浏览器会发送的默认头(比如Cookie、User-Agent、Accept系列头),而且不会实际发送请求。你可以直接从这个Request对象里提取所有需要的头信息,完全符合同步返回的要求。
具体实现代码
JavaScript部分(用于传给run_js)
这段代码会同步返回一个包含所有请求头的普通对象,DrissionPage能直接拿到结果:
(() => { // 构造一个和你实际要发送的Fetch一致的请求对象 // 可根据需求修改:目标URL、请求方法、自定义头、请求体等 const mockRequest = new Request('https://your-target-url.com', { method: 'GET', // 换成你需要的POST/PUT/DELETE等 headers: { 'X-Custom-Header': 'your-custom-value' // 自定义请求头,和实际Fetch保持一致 }, // 如果是POST请求,可添加请求体:body: JSON.stringify({key: 'value'}) }); // 将浏览器原生的Headers对象转换成普通JS对象,方便Python端接收 const requestHeaders = {}; for (const [headerName, headerValue] of mockRequest.headers.entries()) { requestHeaders[headerName] = headerValue; } // 如果你只需要特定的头,也可以直接单独获取,比如: // return { // userAgent: mockRequest.headers.get('User-Agent'), // cookie: mockRequest.headers.get('Cookie') // }; return requestHeaders; })()
Python调用示例
把上面的JS代码传入DrissionPage的run_js即可,和你之前同步获取值的写法一致:
print(tab.run_js(''' (() => { const mockRequest = new Request('https://your-target-url.com', { method: 'GET', headers: { 'X-Custom-Header': 'your-custom-value' } }); const requestHeaders = {}; for (const [headerName, headerValue] of mockRequest.headers.entries()) { requestHeaders[headerName] = headerValue; } return requestHeaders; })() ''', as_expr=True))
为什么这个方法可行?
- 完全同步:
new Request()是同步执行的,不会返回Promise,所以DrissionPage的run_js能直接返回结果,不会得到空对象{}。 - 无实际请求:只是构造一个模拟请求的对象,不会产生网络请求,完全符合你“不触发请求”的需求。
- 头信息完整:会自动包含浏览器默认发送的头(User-Agent、Cookie、Accept、Accept-Language等),加上你自定义的头,和实际Fetch发送的头几乎完全一致。
注意事项
浏览器的受控头(比如Host、Connection、Content-Length)属于底层管控的范围,只有在请求实际发送时才会由浏览器自动添加,无法通过Request对象获取,但这类头一般不是业务中需要提取的内容。
另外,如果你需要模拟带Cookie的请求,只要当前Tab的CookieJar里有目标域名的Cookie,mockRequest会自动带上对应Cookie,不需要手动处理。
关于“同步等待Promise”的补充
其实在浏览器主线程中,没有原生API能让你同步等待Promise(这和JS的单线程异步模型冲突),强行用轮询或者alert阻塞的方法不仅CPU占用高,还可能导致浏览器假死,完全没必要。上面的Request方法是最优雅、最高效的解决方案。
备注:内容来源于stack exchange,提问作者Overclocked Skid

