16

我正在编写一个包装器fetch,我想在发出请求之前向 URL 添加一些内容,例如识别查询参数。我不知道如何使用Request与原始 URL 不同的 URL 来制作给定对象的副本。我的代码如下所示:

// My function which tries to modify the URL of the request
function addLangParameter(request) {
    const newUrl = request.url + "?lang=" + lang;
    return new Request(newUrl, /* not sure what to put here */);
}

// My fetch wrapper
function myFetch(input, init) {
    // Normalize the input into a Request object
    return Promise.resolve(new Request(input, init))
        // Call my modifier function
        .then(addLangParameter)
        // Make the actual request
        .then(request => fetch(request));
}

我尝试将原始请求作为Request构造函数的第二个参数,如下所示:

function addLangParameter(request) {
    const newUrl = request.url + "?lang=" + lang;
    return new Request(newUrl, request);
}

这似乎复制了旧请求的大​​部分属性,但似乎没有保留旧请求的属性body。例如,

const request1 = new Request("/", { method: "POST", body: "test" });
const request2 = new Request("/new", request1);
request2.text().then(body => console.log(body));

我希望记录“测试”,但它记录的是空字符串,因为正文没有被复制。

我是否需要做一些更明确的事情来正确复制所有属性,或者是否有一个不错的快捷方式可以为我做一些合理的事情?

我正在使用github/fetch polyfill,但已经在最新的 Chrome 中测试了 polyfill 和本机fetch实现。

4

1 回答 1

15

看起来您最好的选择是使用BodyRequests 实现的接口读取正文:

https://fetch.spec.whatwg.org/#body

这只能异步完成,因为底层的“消费主体”操作总是异步读取并返回一个承诺。像这样的东西应该工作:

const request = new Request('/old', { method: 'GET' });
const bodyP = request.headers.get('Content-Type') ? request.blob() : Promise.resolve(undefined);
const newRequestP =
  bodyP.then((body) =>
    new Request('/new', {
      method: request.method,
      headers: request.headers,
      body: body,
      referrer: request.referrer,
      referrerPolicy: request.referrerPolicy,
      mode: request.mode,
      credentials: request.credentials,
      cache: request.cache,
      redirect: request.redirect,
      integrity: request.integrity,
    })
  );

这样做之后,newRequestP将是一个可以解决您想要的请求的承诺。幸运的是,无论如何 fetch 都是异步的,所以你的包装器不应该受到很大的阻碍。

(注意:使用没有正文的请求读取.blob()正文似乎返回零长度的 Blob 对象,但在 GET 或 HEAD 请求上指定任何正文,即使是零长度的对象也是不正确的。我相信检查原始请求是否已Content-Type设置是它是否具有主体的准确代理,这是我们真正需要确定的。)

于 2016-01-06T19:50:26.007 回答