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コンストラクターの 2 番目の引数として入れてみました。

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ポリフィルを使用していますが、最新の Chrome でポリフィルとネイティブfetch実装の両方をテストしました。

4

1 に答える 1

15

Bodyリクエストが実装するインターフェースを使用して本文を読み取るのが最善の策のようです。

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

基礎となる「本体の消費」操作は常に非同期で読み取り、promise を返すため、これは非同期でのみ実行できます。このようなものが動作するはずです:

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ば、あなたが望むリクエストに解決する約束になります。幸いなことに、とにかくフェッチは非同期であるため、ラッパーがこれによって大幅に妨げられることはありません。

(注: 本文を.blob()持たないリクエストから off を使用して本文を読み取ると、長さ 0 の Blob オブジェクトが返されるように見えますが、GET または HEAD リクエストで長さ 0 の本文であっても、本文を指定するのは正しくありません。元のリクエストがContent-Type設定されているかどうかを確認することは、実際に決定する必要がある本文があるかどうかの正確なプロキシであると考えています。)

于 2016-01-06T19:50:26.007 に答える