Intercepting and Modifying Network Requests in Puppeteer: A Practical Guide
Learn how to intercept and modify network requests in Puppeteer for efficient web automation, testing, and performance optimization.

Intercepting and modifying network requests in Puppeteer is a powerful way to manage web automation tasks. It allows you to monitor, block, or adjust HTTP requests and responses in real-time. Here's what you can do:
- Monitor Network Activity: Log details like URLs, methods, headers, and payloads.
- Modify Requests: Change headers, redirect URLs, or adjust payloads for API testing and debugging.
- Block Resources: Prevent loading of images, fonts, or scripts to improve performance.
- Simulate Responses: Mock server responses for testing or alter content dynamically.
- Test Error Scenarios: Simulate HTTP status codes like 404 or 500 to test error handling.
Quick Example
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">setRequestInterception</span>(<span class="hljs-literal">true</span>);
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'request'</span>, <span class="hljs-title function_">async</span> (request) => {
<span class="hljs-keyword">if</span> (request.<span class="hljs-title function_">url</span>().<span class="hljs-title function_">includes</span>(<span class="hljs-string">'/api/test'</span>)) {
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">respond</span>({
<span class="hljs-attr">status</span>: <span class="hljs-number">200</span>,
<span class="hljs-attr">contentType</span>: <span class="hljs-string">'application/json'</span>,
<span class="hljs-attr">body</span>: <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>({ <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span> })
});
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">continue</span>();
}
});
This guide explains how to use Puppeteer’s API for request interception, including practical examples for monitoring, modifying, and testing network interactions.
Puppeteer Tutorial #12 | HTTP Interceptors | Intercept Requests
Monitoring Network Requests
Puppeteer makes it possible to monitor network requests, giving you a clear view of web traffic during automation tasks. Here's how you can track and analyze network activity effectively.
Setting Up Request Listeners
Start by enabling request interception and attaching a listener. Here's an example:
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">setRequestInterception</span>(<span class="hljs-literal">true</span>);
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'request'</span>, <span class="hljs-title function_">async</span> (request) => {
<span class="hljs-keyword">if</span> (request.<span class="hljs-title function_">isInterceptResolutionHandled</span>()) <span class="hljs-keyword">return</span>;
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`Intercepted: <span class="hljs-subst">${request.url()}</span>`</span>);
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">continue</span>();
});
Inside the 'request' event listener, you can access and even modify intercepted requests. Just make sure to call request.continue() so the original request isn't blocked.
Filtering Requests by Type
Puppeteer lets you filter network requests based on their type, making it easier to focus on specific traffic. Here's how you can handle requests selectively:
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'request'</span>, <span class="hljs-function"><span class="hljs-params">interceptedRequest</span> =></span> {
<span class="hljs-keyword">if</span> (interceptedRequest.<span class="hljs-title function_">isInterceptResolutionHandled</span>()) <span class="hljs-keyword">return</span>;
<span class="hljs-keyword">const</span> resourceType = interceptedRequest.<span class="hljs-title function_">resourceType</span>();
<span class="hljs-keyword">switch</span>(resourceType) {
<span class="hljs-keyword">case</span> <span class="hljs-string">'image'</span>:
<span class="hljs-comment">// Handle image requests</span>
<span class="hljs-keyword">break</span>;
<span class="hljs-keyword">case</span> <span class="hljs-string">'xhr'</span>:
<span class="hljs-comment">// Handle API calls</span>
<span class="hljs-keyword">break</span>;
<span class="hljs-attr">default</span>:
interceptedRequest.<span class="hljs-title function_">continue</span>();
}
});
By categorizing and prioritizing resource types, you can streamline your network monitoring efforts and focus on what matters most.
Logging Request Data
Once you've filtered the requests, logging their key details can help you uncover useful patterns. Here's a quick overview of some important request properties:
| Request Property | Description | Access Method |
|---|---|---|
| URL | Full request URL | request.url() |
| Method | HTTP method (e.g., GET, POST) | request.method() |
| Headers | Request headers | request.headers() |
| Post Data | Payload sent with the request | request.postData() |
For example, if you want to monitor API requests for pricing data:
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'request'</span>, <span class="hljs-title function_">async</span> (request) => {
<span class="hljs-keyword">if</span> (request.<span class="hljs-title function_">url</span>().<span class="hljs-title function_">includes</span>(<span class="hljs-string">'/api/prices'</span>)) {
<span class="hljs-keyword">const</span> requestData = {
<span class="hljs-attr">url</span>: request.<span class="hljs-title function_">url</span>(),
<span class="hljs-attr">method</span>: request.<span class="hljs-title function_">method</span>(),
<span class="hljs-attr">postData</span>: request.<span class="hljs-title function_">postData</span>()
};
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'Price Request:'</span>, requestData);
}
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">continue</span>();
});
This method allows you to analyze traffic in detail. Always check request.isInterceptResolutionHandled() to prevent conflicts with other handlers.
Changing Outgoing Requests
With Puppeteer, you can tweak outgoing requests to better suit your needs when interacting with web servers.
Header Modifications
You can adjust HTTP headers to include tokens, change user agents, or add custom values.
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">setExtraHTTPHeaders</span>({
<span class="hljs-string">'Authorization'</span>: <span class="hljs-string">'Bearer YOUR_TOKEN'</span>,
<span class="hljs-string">'Custom-Header'</span>: <span class="hljs-string">'CustomValue'</span>
});
For more granular control over individual requests:
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'request'</span>, <span class="hljs-title function_">async</span> (request) => {
<span class="hljs-keyword">if</span> (request.<span class="hljs-title function_">isInterceptResolutionHandled</span>()) <span class="hljs-keyword">return</span>;
<span class="hljs-keyword">const</span> headers = request.<span class="hljs-title function_">headers</span>();
headers[<span class="hljs-string">'Authorization'</span>] = <span class="hljs-string">'Bearer YOUR_TOKEN'</span>;
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">continue</span>({ headers });
});
"Request interception facilitates modification of outgoing requests' properties, such as setting custom headers, altering request methods, or adjusting the request payload." - Saairaamprasad [1]
Next, let’s look at rerouting requests by redirecting URLs.
URL Redirections
Redirect specific requests using the following approach:
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">setRequestInterception</span>(<span class="hljs-literal">true</span>);
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'request'</span>, <span class="hljs-title function_">async</span> (request) => {
<span class="hljs-keyword">if</span> (request.<span class="hljs-title function_">url</span>().<span class="hljs-title function_">includes</span>(<span class="hljs-string">'/api/original'</span>)) {
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">continue</span>({
<span class="hljs-attr">url</span>: request.<span class="hljs-title function_">url</span>().<span class="hljs-title function_">replace</span>(<span class="hljs-string">'/api/original'</span>, <span class="hljs-string">'/api/new'</span>)
});
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">continue</span>();
}
});
This method helps you change API endpoints or reroute requests dynamically.
Request Data Changes
You can also modify payloads for POST and PUT requests. Here’s how:
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'request'</span>, <span class="hljs-title function_">async</span> (request) => {
<span class="hljs-keyword">if</span> (request.<span class="hljs-title function_">isInterceptResolutionHandled</span>()) <span class="hljs-keyword">return</span>;
<span class="hljs-keyword">if</span> (request.<span class="hljs-title function_">url</span>().<span class="hljs-title function_">includes</span>(<span class="hljs-string">'/api/prices'</span>) && request.<span class="hljs-title function_">method</span>() === <span class="hljs-string">'POST'</span>) {
<span class="hljs-keyword">let</span> postData = request.<span class="hljs-title function_">postData</span>();
<span class="hljs-keyword">if</span> (postData) {
postData = postData.<span class="hljs-title function_">replace</span>(<span class="hljs-regexp">/11001/g</span>, <span class="hljs-string">'90210'</span>);
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">continue</span>({ postData });
<span class="hljs-keyword">return</span>;
}
}
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">continue</span>();
});
Here’s a quick reference for modifying different request properties:
| Request Property | How to Modify | Common Use Cases |
|---|---|---|
| Headers | continue({ headers }) | Adding authentication tokens, custom identifiers |
| URL | continue({ url }) | Redirecting endpoints, rerouting requests |
| Post Data | continue({ postData }) | Updating form data, altering API payloads |
Note: Changing requests can affect performance, so it’s best to intercept only when necessary. These methods provide you with precise control over outgoing requests in your automation workflows.
Managing Server Responses
Puppeteer allows you to handle and modify server responses, making it a powerful tool for web automation. This section builds on earlier techniques for request modification and focuses on controlling server responses to give you full control over network interactions.
Response Monitoring
You can track incoming server responses by setting up a response event listener:
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'response'</span>, <span class="hljs-title function_">async</span> (response) => {
<span class="hljs-keyword">const</span> url = response.<span class="hljs-title function_">url</span>();
<span class="hljs-keyword">const</span> status = response.<span class="hljs-title function_">status</span>();
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`Response from <span class="hljs-subst">${url}</span>: <span class="hljs-subst">${status}</span>`</span>);
<span class="hljs-keyword">if</span> (response.<span class="hljs-title function_">url</span>().<span class="hljs-title function_">includes</span>(<span class="hljs-string">'/api/prices'</span>)) {
<span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.<span class="hljs-title function_">json</span>();
<span class="hljs-comment">// Process response data</span>
}
});
This snippet logs details like the URL, status codes, and headers, helping you analyze how the server behaves. Beyond monitoring, you can modify response content dynamically to suit your needs.
Modifying Response Content
To customize how responses are handled, use interception. Here's an example:
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'request'</span>, <span class="hljs-title function_">async</span> (request) => {
<span class="hljs-keyword">if</span> (request.<span class="hljs-title function_">url</span>().<span class="hljs-title function_">includes</span>(<span class="hljs-string">'/api/prices'</span>)) {
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">respond</span>({
<span class="hljs-attr">status</span>: <span class="hljs-number">200</span>,
<span class="hljs-attr">contentType</span>: <span class="hljs-string">'application/json'</span>,
<span class="hljs-attr">body</span>: <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>({
<span class="hljs-attr">price</span>: <span class="hljs-number">99.99</span>,
<span class="hljs-attr">currency</span>: <span class="hljs-string">'USD'</span>,
<span class="hljs-attr">zipCode</span>: <span class="hljs-string">'90210'</span>
})
});
<span class="hljs-keyword">return</span>;
}
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">continue</span>();
});
This technique is particularly useful for testing APIs by mocking responses or tweaking data in specific scenarios.
Testing HTTP Status Codes
Once you’ve mastered modifying content, you can simulate various HTTP status codes to test error handling. Here’s how:
| Status Code | Use Case | Implementation Example |
|---|---|---|
| 200 | Success response | status: 200, body: JSON.stringify(successData) |
| 404 | Missing resource | status: 404, body: 'Not Found' |
| 500 | Server error | status: 500, body: 'Internal Server Error' |
For example:
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'request'</span>, <span class="hljs-title function_">async</span> (request) => {
<span class="hljs-keyword">if</span> (request.<span class="hljs-title function_">url</span>().<span class="hljs-title function_">includes</span>(<span class="hljs-string">'/api/test-endpoint'</span>)) {
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">respond</span>({
<span class="hljs-attr">status</span>: <span class="hljs-number">404</span>,
<span class="hljs-attr">contentType</span>: <span class="hljs-string">'text/plain'</span>,
<span class="hljs-attr">body</span>: <span class="hljs-string">'Not Found!'</span>
});
<span class="hljs-keyword">return</span>;
}
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">continue</span>();
});
"Request interception in Puppeteer allows you to observe, modify, or block outgoing HTTP requests and incoming responses. This feature is handy when optimizing page loading, simulating various network conditions, or handling dynamic content loading." – Saairaamprasad [1]
Pro Tip: While intercepting responses can be powerful, use it sparingly. Overusing interception might slow down your automation scripts or introduce unnecessary complexity.
sbb-itb-23997f1
Request Interception Guidelines
Request interception is a powerful tool, but it requires careful use to ensure smooth performance and maintain reliability. Below are practical steps for managing sessions, improving speed, and resolving common issues.
Managing User Sessions
Here’s how you can handle user sessions effectively:
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">setRequestInterception</span>(<span class="hljs-literal">true</span>);
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'request'</span>, <span class="hljs-title function_">async</span> (request) => {
<span class="hljs-keyword">if</span> (!request.<span class="hljs-title function_">isInterceptResolutionHandled</span>()) {
<span class="hljs-keyword">const</span> headers = request.<span class="hljs-title function_">headers</span>();
headers[<span class="hljs-string">'Authorization'</span>] = <span class="hljs-string">'Bearer '</span> + yourAuthToken;
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">continue</span>({ headers });
}
});
Always check the interception status before modifying headers to avoid conflicts with other interceptors.
Speed Optimization
Blocking unnecessary resources can significantly cut down page load times - sometimes by as much as 500 milliseconds [3]. Here’s an example:
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">route</span>(<span class="hljs-string">'**/*'</span>, <span class="hljs-function">(<span class="hljs-params">route</span>) =></span> {
<span class="hljs-keyword">const</span> resourceType = route.<span class="hljs-title function_">request</span>().<span class="hljs-title function_">resourceType</span>();
<span class="hljs-keyword">if</span> ([<span class="hljs-string">'image'</span>, <span class="hljs-string">'stylesheet'</span>, <span class="hljs-string">'font'</span>].<span class="hljs-title function_">includes</span>(resourceType)) {
route.<span class="hljs-title function_">abort</span>();
<span class="hljs-keyword">return</span>;
}
route.<span class="hljs-title function_">continue</span>();
});
| Resource Type | Action | Impact |
|---|---|---|
| Images | Block | Speeds up page loading |
| Stylesheets | Selective loading | Saves bandwidth |
| Analytics | Block | Reduces network overhead |
| API Calls | Allow | Keeps essential functionality |
When performance issues occur, these resource management strategies can help.
Troubleshooting Tips
Improper handling is a common source of issues. Here are some practical fixes:
"Once request interception is enabled, every request will stall unless it's continued, responded or aborted."
- Resolution Handling: Use
isInterceptResolutionHandledchecks to prevent race conditions. - Multiple Handlers: Assign priorities when using multiple intercept handlers:
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">continue</span>({
<span class="hljs-attr">priority</span>: <span class="hljs-number">1</span>,
<span class="hljs-attr">headers</span>: modifiedHeaders
});
- Stalled Requests: Ensure all requests are resolved properly:
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'request'</span>, <span class="hljs-title function_">async</span> (request) => {
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">if</span> (!request.<span class="hljs-title function_">isInterceptResolutionHandled</span>()) {
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">continue</span>();
}
} <span class="hljs-keyword">catch</span> (error) {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">'Request handling error:'</span>, error);
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">abort</span>();
}
});
Keep your interception logic straightforward. Overcomplicated rules can slow things down and make your code harder to maintain.
Key Takeaways
Puppeteer's request interception provides developers with powerful tools to refine web automation tasks. These tools allow for:
- Request Modification: Adjust headers, methods, and payloads to control data flow effectively.
- Response Handling: Customize server responses for various testing needs.
- Resource Management: Improve performance by selectively handling requests.
Practical Applications
Request interception has proven helpful in many scenarios. For instance, in a recent e-commerce case, modifying product price requests based on zip codes demonstrated its utility [2].
Some common uses include:
- Mocking API responses for testing
- Enhancing data scraping by modifying headers
- Boosting load speeds by blocking unnecessary resources
- Strengthening security with custom authentication tokens
These examples highlight how request interception can address both development and operational challenges, paving the way for advanced automation techniques.
Using Puppeteer with Latenode
Latenode simplifies implementing these strategies. Here's a sample workflow to show how Puppeteer integrates with Latenode:
<span class="hljs-comment">// Example workflow setup in Latenode</span>
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">setRequestInterception</span>(<span class="hljs-literal">true</span>);
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'request'</span>, <span class="hljs-title function_">async</span> (request) => {
<span class="hljs-keyword">if</span> (request.<span class="hljs-title function_">resourceType</span>() === <span class="hljs-string">'fetch'</span>) {
<span class="hljs-keyword">const</span> modifiedHeaders = {
...request.<span class="hljs-title function_">headers</span>(),
<span class="hljs-string">'Custom-Header'</span>: <span class="hljs-string">'Modified-Value'</span>
};
<span class="hljs-keyword">await</span> request.<span class="hljs-title function_">continue</span>({ <span class="hljs-attr">headers</span>: modifiedHeaders });
}
});
This example demonstrates how you can modify request headers dynamically to suit your specific needs.
Related posts
- Installing and Configuring Puppeteer: Solving Common Dependency and Chromium Issues
- Network Response Analysis and Processing in Puppeteer: Monitoring and Modification
- User-Agent Management in Puppeteer for Device Emulation
- Cache Management in Puppeteer: Disabling, Clearing, and Performance Optimization



