Node.jsのfetchを使ってページを取得する

基本はブラウザと同じです。ただし、awaitがトップレベルでも使えます。(async functionの中にいなくても良い) 自分はnode-fetchを使ったことがないがおそらく同じ感じでしょう。

記事を書いた時点でNode.jsのバージョンはv18.16.0です。

取得

try {
    const res = await fetch("https://example.com/");
    if (!res.ok) {
        throw new Error(`response error: ${res.status} ${res.statusText}`);
    }

    const json = await res.json();
    console.log(json);
} catch (error) {
    console.error(error.message);
}  

HTMLが返ってくる場合は、res.json()ではなくres.text()を使います。なお、これらはUTF-8で解釈するのでもしサーバが別な文字コードを返してくる場合はres.arrayBuffer()とTextEncoderを使う必要があります。

// fetchしてresを受け取った後から
const buf = await res.arrayBuffer();
const decoder = new TextDecoder("windows-31j"); // たとえばwindows-31jで返してきた
const text = decoder.decode(buf);

リクエストヘッダの追加

リクエストヘッダに何か追加したい場合はfetchの第二引数にオブジェクトを渡してやります。

const res = fetch("https://example.com/", { headers: { "User-Agent": "foo" }});

注意点として第二引数はあくまでリクエストヘッダを表すheadersをもつオブジェクトだということです。

const headers = { "User-Agent": "foo" };
const res = fetch("https://example.com/", headers);

などとやっても駄目です。

gzipなどの圧縮について

デフォルトでContent-Encodingにbr,gzip,deflateをつけて送信し、圧縮されていれば自動的に展開してくれるのでユーザーが何かする必要はないようです。