DenoではfetchでHTTPリクエストを送る際、リクエストヘッダーのUser-AgentにDeno/<バージョン名>という値が入っています。この部分を変える方法です。
デフォルトのUser-Agent
デフォルトのUser-Agentヘッダーは以下のコードで確認できます。
const res = await fetch("https://dump-headers.herokuapp.com/");
console.log(await res.json());
上のコードを実行すると、User-Agentヘッダーが「Deno/1.24.1」であることが分かります。もちろんバージョン番号部分はお使いのDenoのバージョンによって異なります。
また、単にnavigator.userAgentとすればプログラムから取得することもできます。
console.log(navigator.userAgent); // "Deno/1.24.1"
User-Agentヘッダーの書き換え
Requestオブジェクトを使用して、以下のように書きます。
const req = new Request("https://dump-headers.herokuapp.com/", {
headers: {
"user-agent": "hello!!!", // User-Agentヘッダーを"hello!!!"に設定
},
});
const res = await fetch(req);
console.log(await res.json());
上記のコードを実行すると、User-Agentが目的の値に書き変わっているのが分かると思います。
ブラウザと非互換なふるまい
Denoに実装されているfetchはブラウザと同様のAPIです。
しかし上記のコード、ブラウザで実行してもUser-Agentヘッダーを書き換えることはできません。
このように、ブラウザとDenoの間で微妙に(意図的に)挙動が異なる部分があります。
挙動が異なる部分が文書化されているので、ちょっと読んでみましょう。
- The Deno user agent does not have a cookie jar. As such, the
set-cookie
header on a response is not processed, or filtered from the visible response
headers.- Deno does not follow the same-origin policy, because the Deno user agent
currently does not have the concept of origins, and it does not have a cookie
jar. This means Deno does not need to protect against leaking authenticated
data cross origin. Because of this Deno does not implement the following
sections of the WHATWGfetchspecification:
- Section
3.1. 'Origin' header.- Section
3.2. CORS protocol.- Section
3.5. CORB.- Section
3.6. 'Cross-Origin-Resource-Policy' header.Atomic HTTP redirect handling.- The
opaqueredirectresponse type.- A
fetchwith aredirectmode ofmanualwill return abasicresponse
rather than anopaqueredirectresponse.- The specification is vague on how
file:URLs are to be handled.
Firefox is the only mainstream browser that implements fetchingfile:URLs,
and even then it doesn't work by default. As of Deno 1.16, Deno supports
fetching local files. See the next section for details.- The
requestandresponseheader guards are implemented, but unlike
browsers do not have any constraints on which header names are allowed.- The
referrer,referrerPolicy,mode,credentials,cache,integrity,
keepalive, andwindowproperties and their relevant behaviours in
RequestInitare not implemented. The relevant fields are not present on the
Requestobject.- Request body upload streaming is supported (on HTTP/1.1 and HTTP/2). Unlike
the current fetch proposal, the implementation supports duplex streaming.- The
set-cookieheader is not concatenated when iterated over in the
headersiterator. This behaviour is in the
process of being specified.https://deno.land/manual/runtime/web_platform_apis#spec-deviations
要約すると、主に以下の点がブラウザの挙動と異なると言っています。
- Cookieの処理を行わない
- ブラウザにあるCORS制限はない
- file URLに対するfetch(=ローカルファイルfetch)を許可する
- Requestヘッダーに指定できるヘッダー名に制約はない(→ブラウザの禁止ヘッダー名を参照)
- 双方向ストリーミングが可能
- set-cookie ヘッダーの処理方法
実はUser-Agentヘッダー自体は禁止ヘッダー名の中に含まれていません。
User-AgentヘッダーがChromeで書き換えられないのは、単に古い挙動が放置されているからだと思われます。
(実際、FirefoxではUser-Agentヘッダーを書き換えることができます。)
このように、Denoに実装されているfetchとブラウザに実装されているfetchは微妙に挙動が異なり、サーバーサイドでも使いやすいように工夫されています。
まとめ
- DenoのデフォルトのUser-Agentは
Deno/<バージョン名>という値- これは
navigator.userAgentで取得できる
- これは
-
Requestオブジェクトを使うとUser-Agentヘッダーを書き換えることができる - Denoのfetchはブラウザと挙動が異なる部分がある
ちなみに、Denoのfetchの挙動については、cloudflareやNode.jsとともにWinter CGで標準化されている最中です。