- since: v1.8
Whenever a network route is set up with [method: Page.route
] or [method: BrowserContext.route
], the Route
object
allows to handle the route.
Learn more about networking.
- since: v1.8
Aborts the route's request.
- since: v1.8
errorCode
?<[string]>
Optional error code. Defaults to failed
, could be one of the following:
'aborted'
- An operation was aborted (due to user action)'accessdenied'
- Permission to access a resource, other than the network, was denied'addressunreachable'
- The IP address is unreachable. This usually means that there is no route to the specified host or network.'blockedbyclient'
- The client chose to block the request.'blockedbyresponse'
- The request failed because the response was delivered along with requirements which are not met ('X-Frame-Options' and 'Content-Security-Policy' ancestor checks, for instance).'connectionaborted'
- A connection timed out as a result of not receiving an ACK for data sent.'connectionclosed'
- A connection was closed (corresponding to a TCP FIN).'connectionfailed'
- A connection attempt failed.'connectionrefused'
- A connection attempt was refused.'connectionreset'
- A connection was reset (corresponding to a TCP RST).'internetdisconnected'
- The Internet connection has been lost.'namenotresolved'
- The host name could not be resolved.'timedout'
- An operation timed out.'failed'
- A generic failure occurred.
- since: v1.8
- langs:
- alias-java: resume
- alias-python: continue_
Continues route's request with optional overrides.
Usage
await page.route('**/*', (route, request) => {
// Override headers
const headers = {
...request.headers(),
foo: 'foo-value', // set "foo" header
bar: undefined, // remove "bar" header
};
route.continue({headers});
});
page.route("**/*", route -> {
// Override headers
Map<String, String> headers = new HashMap<>(route.request().headers());
headers.put("foo", "foo-value"); // set "foo" header
headers.remove("bar"); // remove "bar" header
route.resume(new Route.ResumeOptions().setHeaders(headers));
});
async def handle(route, request):
# override headers
headers = {
**request.headers,
"foo": "foo-value" # set "foo" header
"bar": None # remove "bar" header
}
await route.continue_(headers=headers)
await page.route("**/*", handle)
def handle(route, request):
# override headers
headers = {
**request.headers,
"foo": "foo-value" # set "foo" header
"bar": None # remove "bar" header
}
route.continue_(headers=headers)
page.route("**/*", handle)
await page.RouteAsync("**/*", route =>
{
var headers = new Dictionary<string, string>(route.Request.Headers) { { "foo", "bar" } };
headers.Remove("origin");
route.ContinueAsync(headers);
});
- since: v1.8
url
<[string]>
If set changes the request URL. New URL must have same protocol as original one.
- since: v1.8
method
<[string]>
If set changes the request method (e.g. GET or POST).
- since: v1.8
- langs: js, python
postData
<[string]|[Buffer]|[Serializable]>
If set changes the post data of request.
- since: v1.8
- langs: java
postData
<[string]|[Buffer]>
If set changes the post data of request.
- since: v1.8
- langs: csharp
postData
<[Buffer]>
If set changes the post data of request.
- since: v1.8
headers
<[Object]<[string], [string]>>
If set changes the request HTTP headers. Header values will be converted to a string.
- since: v1.23
When several routes match the given pattern, they run in the order opposite to their registration. That way the last registered route can always override all the previous ones. In the example below, request will be handled by the bottom-most handler first, then it'll fall back to the previous one and in the end will be aborted by the first registered route.
Usage
await page.route('**/*', route => {
// Runs last.
route.abort();
});
await page.route('**/*', route => {
// Runs second.
route.fallback();
});
await page.route('**/*', route => {
// Runs first.
route.fallback();
});
page.route("**/*", route -> {
// Runs last.
route.abort();
});
page.route("**/*", route -> {
// Runs second.
route.fallback();
});
page.route("**/*", route -> {
// Runs first.
route.fallback();
});
await page.route("**/*", lambda route: route.abort()) # Runs last.
await page.route("**/*", lambda route: route.fallback()) # Runs second.
await page.route("**/*", lambda route: route.fallback()) # Runs first.
page.route("**/*", lambda route: route.abort()) # Runs last.
page.route("**/*", lambda route: route.fallback()) # Runs second.
page.route("**/*", lambda route: route.fallback()) # Runs first.
await page.RouteAsync("**/*", route => {
// Runs last.
await route.AbortAsync();
});
await page.RouteAsync("**/*", route => {
// Runs second.
await route.FallbackAsync();
});
await page.RouteAsync("**/*", route => {
// Runs first.
await route.FallbackAsync();
});
Registering multiple routes is useful when you want separate handlers to handle different kinds of requests, for example API calls vs page resources or GET requests vs POST requests as in the example below.
// Handle GET requests.
await page.route('**/*', route => {
if (route.request().method() !== 'GET') {
route.fallback();
return;
}
// Handling GET only.
// ...
});
// Handle POST requests.
await page.route('**/*', route => {
if (route.request().method() !== 'POST') {
route.fallback();
return;
}
// Handling POST only.
// ...
});
// Handle GET requests.
page.route("**/*", route -> {
if (!route.request().method().equals("GET")) {
route.fallback();
return;
}
// Handling GET only.
// ...
});
// Handle POST requests.
page.route("**/*", route -> {
if (!route.request().method().equals("POST")) {
route.fallback();
return;
}
// Handling POST only.
// ...
});
# Handle GET requests.
def handle_post(route):
if route.request.method != "GET":
route.fallback()
return
# Handling GET only.
# ...
# Handle POST requests.
def handle_post(route):
if route.request.method != "POST":
route.fallback()
return
# Handling POST only.
# ...
await page.route("**/*", handle_get)
await page.route("**/*", handle_post)
# Handle GET requests.
def handle_post(route):
if route.request.method != "GET":
route.fallback()
return
# Handling GET only.
# ...
# Handle POST requests.
def handle_post(route):
if route.request.method != "POST":
route.fallback()
return
# Handling POST only.
# ...
page.route("**/*", handle_get)
page.route("**/*", handle_post)
// Handle GET requests.
await page.RouteAsync("**/*", route => {
if (route.Request.Method != "GET") {
await route.FallbackAsync();
return;
}
// Handling GET only.
// ...
});
// Handle POST requests.
await page.RouteAsync("**/*", route => {
if (route.Request.Method != "POST") {
await route.FallbackAsync();
return;
}
// Handling POST only.
// ...
});
One can also modify request while falling back to the subsequent handler, that way intermediate route handler can modify url, method, headers and postData of the request.
await page.route('**/*', (route, request) => {
// Override headers
const headers = {
...request.headers(),
foo: 'foo-value', // set "foo" header
bar: undefined, // remove "bar" header
};
route.fallback({headers});
});
page.route("**/*", route -> {
// Override headers
Map<String, String> headers = new HashMap<>(route.request().headers());
headers.put("foo", "foo-value"); // set "foo" header
headers.remove("bar"); // remove "bar" header
route.fallback(new Route.ResumeOptions().setHeaders(headers));
});
async def handle(route, request):
# override headers
headers = {
**request.headers,
"foo": "foo-value" # set "foo" header
"bar": None # remove "bar" header
}
await route.fallback(headers=headers)
await page.route("**/*", handle)
def handle(route, request):
# override headers
headers = {
**request.headers,
"foo": "foo-value" # set "foo" header
"bar": None # remove "bar" header
}
route.fallback(headers=headers)
page.route("**/*", handle)
await page.RouteAsync("**/*", route =>
{
var headers = new Dictionary<string, string>(route.Request.Headers) { { "foo", "foo-value" } };
headers.Remove("bar");
route.FallbackAsync(headers);
});
- since: v1.23
url
<[string]>
If set changes the request URL. New URL must have same protocol as original one. Changing the URL won't affect the route matching, all the routes are matched using the original request URL.
- since: v1.23
method
<[string]>
If set changes the request method (e.g. GET or POST).
- since: v1.23
- langs: js, python
postData
<[string]|[Buffer]|[Serializable]>
If set changes the post data of request.
- since: v1.23
- langs: java
postData
<[string]|[Buffer]>
If set changes the post data of request.
- since: v1.23
- langs: csharp
postData
<[Buffer]>
If set changes the post data of request.
- since: v1.23
headers
<[Object]<[string], [string]>>
If set changes the request HTTP headers. Header values will be converted to a string.
- since: v1.29
- returns: <[APIResponse]>
Performs the request and fetches result without fulfilling it, so that the response could be modified and then fulfilled.
Usage
await page.route('https://dog.ceo/api/breeds/list/all', async route => {
const response = await route.fetch();
const json = await response.json();
json.message['big_red_dog'] = [];
await route.fulfill({ response, json });
});
page.route("https://dog.ceo/api/breeds/list/all", route -> {
APIResponse response = route.fetch();
JsonObject json = new Gson().fromJson(response.text(), JsonObject.class);
JsonObject message = itemObj.get("json").getAsJsonObject();
message.set("big_red_dog", new JsonArray());
route.fulfill(new Route.FulfillOptions()
.setResponse(response)
.setBody(json.toString()));
});
async def handle(route):
response = await route.fulfill()
json = await response.json()
json["message"]["big_red_dog"] = []
await route.fulfill(response=response, json=json)
await page.route("https://dog.ceo/api/breeds/list/all", handle)
def handle(route):
response = route.fulfill()
json = response.json()
json["message"]["big_red_dog"] = []
route.fulfill(response=response, json=json)
page.route("https://dog.ceo/api/breeds/list/all", handle)
await page.RouteAsync("https://dog.ceo/api/breeds/list/all", async route =>
{
var response = await route.FetchAsync();
dynamic json = await response.JsonAsync();
json.message.big_red_dog = new string[] {};
await route.FulfillAsync(new() { Response = response, Json = json });
});
- since: v1.29
url
<[string]>
If set changes the request URL. New URL must have same protocol as original one.
- since: v1.29
method
<[string]>
If set changes the request method (e.g. GET or POST).
- langs: js, python
- since: v1.29
postData
<[string]|[Buffer]|[Serializable]>
Allows to set post data of the request. If the data parameter is an object, it will be serialized to json string
and content-type
header will be set to application/json
if not explicitly set. Otherwise the content-type
header will be
set to application/octet-stream
if not explicitly set.
- langs: java
- since: v1.29
postData
<[string]|[Buffer]>
If set changes the post data of request.
- since: v1.29
- langs: csharp
postData
<[Buffer]>
If set changes the post data of request.
- since: v1.29
headers
<[Object]<[string], [string]>>
If set changes the request HTTP headers. Header values will be converted to a string.
- since: v1.8
Fulfills route's request with given response.
Usage
An example of fulfilling all requests with 404 responses:
await page.route('**/*', route => {
route.fulfill({
status: 404,
contentType: 'text/plain',
body: 'Not Found!'
});
});
page.route("**/*", route -> {
route.fulfill(new Route.FulfillOptions()
.setStatus(404)
.setContentType("text/plain")
.setBody("Not Found!"));
});
await page.route("**/*", lambda route: route.fulfill(
status=404,
content_type="text/plain",
body="not found!"))
page.route("**/*", lambda route: route.fulfill(
status=404,
content_type="text/plain",
body="not found!"))
await page.RouteAsync("**/*", route => route.FulfillAsync(new ()
{
Status = 404,
ContentType = "text/plain",
Body = "Not Found!")
});
An example of serving static file:
await page.route('**/xhr_endpoint', route => route.fulfill({ path: 'mock_data.json' }));
page.route("**/xhr_endpoint", route -> route.fulfill(
new Route.FulfillOptions().setPath(Paths.get("mock_data.json"))));
await page.route("**/xhr_endpoint", lambda route: route.fulfill(path="mock_data.json"))
page.route("**/xhr_endpoint", lambda route: route.fulfill(path="mock_data.json"))
await page.RouteAsync("**/xhr_endpoint", route => route.FulfillAsync(new() { Path = "mock_data.json" }));
- since: v1.8
status
<[int]>
Response status code, defaults to 200
.
- since: v1.8
headers
<[Object]<[string], [string]>>
Response headers. Header values will be converted to a string.
- since: v1.8
contentType
<[string]>
If set, equals to setting Content-Type
response header.
- since: v1.8
- langs: js, python
body
<[string]|[Buffer]>
Response body.
- since: v1.8
- langs: csharp, java
body
<[string]>
Optional response body as text.
- since: v1.9
- langs: csharp, java
bodyBytes
<[Buffer]>
Optional response body as raw bytes.
- since: v1.29
- langs: js, python
json
<[Serializable]>
JSON response. This method will set the content type to application/json
if not set.
- since: v1.29
- langs: csharp
json
<[JsonElement]>
JSON response. This method will set the content type to application/json
if not set.
Usage
await page.RouteAsync("https://dog.ceo/api/breeds/list/all", async route =>
{
var json = /* JsonElement with test payload */;
await route.FulfillAsync(new () { Json: json });
});
- since: v1.8
path
<[path]>
File path to respond with. The content type will be inferred from file extension. If path
is a relative path, then it
is resolved relative to the current working directory.
- since: v1.15
response
<[APIResponse]>
[APIResponse] to fulfill route's request with. Individual fields of the response (such as headers) can be overridden using fulfill options.
- since: v1.8
- returns: <[Request]>
A request to be routed.