I'm just playing around the with Fetch
API and I came across something that I can't seem to find the answer to. If I create a new request object like so:
let request = new Request('http://www.foo.com', {
method: 'GET',
mode: 'no-cors',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded'
})
});
If I then try and modify the URL (append a query string to it) I receive an error in the browser (Cannot assign to read only property
). I know that usually with an object, you can set writable
to 'True' but does this work the same for a request object?
The reason that I ask is that I am trying to append a querystring to the end of the URL. These options
are in another object, which I've got the values of and concatenated into a string so that it's something like:
number=1&id=130&foo=bar
etc.
Am I trying to over engineer what I am doing here?
You can copy all the properties from the old request into a new one with a new url like so:
const init = {
method: 'GET',
mode: 'no-cors',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded'
})
};
const oldRequest = new Request("https://old-url.com", init);
const newRequest = new Request("https://new-url.com", oldRequest);
console.log(newRequest.mode === oldRequest.mode); // true
console.log(newRequest.headers.get('Content-Type') === oldRequest.headers.get('Content-Type')); // true
console.log(newRequest.method === oldRequest.method); // true
Request
object is immutable by design, don't try to change it.
I wish clone()
instance method accepted options to be able to to tweak the cloned object, but it doesn't. So I came up with this function:
function appendQuery(urlOrReq, queryString) {
// make sure we deal with a Request object even if we got a URL string
const req = urlOrReq instanceof Request ? urlOrReq : new Request(urlOrReq);
const {
cache, credentials, headers, integrity, method,
mode, redirect, referrer, referrerPolicy, url, body
} = req;
// Don't add query string if there's none
const urlWithQuery = url + (!queryString ? '' : '?' + queryString);
return new Request(urlWithQuery, {
cache, credentials, headers, integrity, method,
mode, redirect, referrer, referrerPolicy, body
})
}
Here's the same in TypeScript (only the first line is different):
function appendQuery(urlOrReq: RequestInfo, queryString?: string): Request {
// make sure we deal with a Request object even if we got a URL string
const req = urlOrReq instanceof Request ? urlOrReq : new Request(urlOrReq);
const {
cache, credentials, headers, integrity, method,
mode, redirect, referrer, referrerPolicy, url, body
} = req;
// Don't add query string if there's none
const urlWithQuery = url + (!queryString ? '' : '?' + queryString);
return new Request(urlWithQuery, {
cache, credentials, headers, integrity, method,
mode, redirect, referrer, referrerPolicy, body
})
}
Here's how it works:
const req = new Request('https://google.com')
appendQuery(req, 'foo=42')
// => Request {method: "GET", url: "https://google.com?foo=42", headers: Headers, destination: "", referrer: "about:client", …}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With