在 ES6 中修改新请求对象的 URL

zik*_*zik 7 javascript request ecmascript-6 fetch-api

我只是在玩FetchAPI,我遇到了一些我似乎无法找到答案的东西。如果我像这样创建一个新的请求对象:

let request = new Request('http://www.foo.com', {
  method: 'GET',
  mode: 'no-cors',
  headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded'
  })
});
Run Code Online (Sandbox Code Playgroud)

如果我然后尝试修改 URL(向其附加查询字符串),我会在浏览器中收到错误 ( Cannot assign to read only property)。我知道通常对于一个对象,您可以将其设置writable为“True”,但是这对于请求对象是否相同?

我问的原因是我试图将查询字符串附加到 URL 的末尾。这些options在另一个对象中,我已经得到了它的值并连接成一个字符串,所以它是这样的:

number=1&id=130&foo=bar 等等。

我是否试图过度设计我在这里所做的事情?

Cyp*_*eld 11

您可以将旧请求中的所有属性复制到具有新 url 的新请求中,如下所示:

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
Run Code Online (Sandbox Code Playgroud)

  • 这是一个更好的响应,应该是选定的响应。 (2认同)

Mik*_*sin 5

Request 对象在设计上是不可变的,不要试图改变它。

我希望clone()实例方法接受能够调整克隆对象的选项,但事实并非如此。所以我想出了这个功能:

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
  })
}
Run Code Online (Sandbox Code Playgroud)

这在 TypeScript 中是一样的(只有第一行不同):

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
  })
}
Run Code Online (Sandbox Code Playgroud)

这是它的工作原理:

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", …}
Run Code Online (Sandbox Code Playgroud)