How to modify the url of a request object in fetch API?
Asked Answered
H

3

5

I am using Cloudflare worker which is triggered by HTTP requests. I want to take the incoming request, change the url but leave all other properties untouched, and then issue the request. The structure is loke the following:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {

  #change the value of request.url and then...

  return fetch(request)
    .then(response => {
        return response;
    });
}
Hemipode answered 31/5, 2020 at 15:34 Comment(0)
F
5

To clone a Request object, but change the URL, you can do this:

new Request("https://example.com/the/new/url", originalRequest);

Try it in your browser console:

let originalRequest = new Request("https://example.com")
let newRequest = new Request("https://voxviva.app", originalRequest);

Inspect newRequest. You will not see the old URL anywhere.

Foghorn answered 10/6, 2022 at 6:48 Comment(1)
Note that this does not copy the priority of the request, since that is not exposed as a property. All other options seem to be exposed as a property, so I think they'll be copied over correctly. Though I'm not sure if this api was intended to be used this way.Calcifuge
B
0

In my case, I needed to monkey-patch window.fetch for both options - url as string and also Request object.

This answer https://mcmap.net/q/671713/-how-do-i-copy-a-request-object-with-a-different-url covers how you can change url in the Request object by duplicating the existing Request object.

I myself implemented a solution where the Request is actually changed into simple window.fetch with url & options.

(function (window) {
  const original = window.fetch;
    window.fetch = async function () {
      let [url, config] = arguments;
      if (typeof url === 'string') {
        const newUrl = customChangeUrl(url);
        return original.apply(window, [newUrl, config]);
      }
      if (typeof url === 'object') {
        const request = url;
        const blob = await request.blob();
        const body = blob.size > 0 ? blob : undefined;
        config = {
          body,
          cache: request.cache,
          credentials: request.credentials,
          headers: request.headers,
          integrity: request.integrity,
          keepalive: request.keepalive,
          method: request.method,
          mode: request.mode,
          redirect: request.redirect,
          referrer: request.referrer,
          referrerPolicy: request.referrerPolicy,
          signal: request.signal,
        }

        const newUrl = customChangeUrl(request.url);
        return original.apply(window, [newUrl, config]);
      }
    };
})(window);
Boak answered 11/5, 2023 at 13:10 Comment(0)
N
-2

You can do this:

async function handleRequest(request) {

  #change the value of request.url and then...

  return fetch({...request, url: "someUrl"})
    .then(response => {
        return response;
    });
}

This will overwrite the url with "someUrl" Hope this helps :)

Normy answered 31/5, 2020 at 16:19 Comment(1)
This won't work because most properties of Request are not enumerable, so they won't be included in the spread. Try it: const request = new Request({method: 'POST', url: '/'}); const requestData = {...request}; console.log(requestData.method) - it will print undefined instead of 'POST'.Mezzosoprano

© 2022 - 2025 — McMap. All rights reserved.