如何使用其他URL复制Request对象? [英] How do I copy a Request object with a different URL?

查看:143
本文介绍了如何使用其他URL复制Request对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个围绕 fetch 的包装器,我想在发出请求前向URL添加内容,例如:识别查询参数。我无法弄清楚如何使用与原始URL不同的URL复制给定的 Request 对象。我的代码如下所示:

I'm writing a wrapper around fetch that I would like to add something to the URL before making the request e.g. identifying query parameters. I can't figure out how to make a copy of a given a Request object with a different URL than the original. My code looks like:

// 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));
}

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

I tried putting the original request as the second arguent to the Request constructor, like so:

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

这似乎复制了旧请求的大​​多数属性但没有似乎保留旧请求的正文。例如,

which seems to copy most of the attributes of the old request but doesn't seem to preserve the body of the old request. For example,

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

我希望记录test,但它会记录空字符串,因为正文是没有被复制过来。

I would expect to log "test", but instead it logs the empty string, because the body is not copied over.

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

Do I need to do something more explicit to copy all of the attributes correctly, or is there a nice shortcut that will do something reasonable for me?

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

I'm using the github/fetch polyfill, but have tested with both the polyfill and the native fetch implementation in the lastest Chrome.

推荐答案

看起来你最好的选择是使用Requests实现的 Body 界面阅读正文:

It looks like your best bet is to read the body using the Body interface that Requests implement:

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

这只能异步完成,因为底层的消耗体操作总是异步读取并返回一个promise。这样的事情应该有效:

This can only be done asynchronously since the underlying "consume body" operation always reads asynchronously and returns a promise. Something like this should work:

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无论如何都是异步的,所以你的包装器不应该受到这种阻碍。

After doing that, newRequestP will be a promise that resolves to the request you want. Luckily, fetch is asynchronous anyway so your wrapper shouldn't be significantly hampered by this.

(注意:使用 .blob()读取正文关闭没有正文的请求似乎返回一个零长度的Blob对象,但是在GET或HEAD请求中指定任何正文,甚至是零长度的正文都是不正确的。相信检查原始请求是否具有 Content-Type set是一个准确的代理,它是否有一个正文,这是我们真正需要确定的。)

(Note: Reading the body using .blob() off of a request that does not have a body seems to return a zero-length Blob object, but it's incorrect to specify any body, even a zero-length one, on a GET or HEAD request. I believe that checking if the original request had Content-Type set is an accurate proxy for whether it has a body, which is what we really need to determine.)

这篇关于如何使用其他URL复制Request对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆