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 WHATWGfetch
specification:
- 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
opaqueredirect
response type.- A
fetch
with aredirect
mode ofmanual
will return abasic
response
rather than anopaqueredirect
response.- 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
request
andresponse
header 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
, andwindow
properties and their relevant behaviours in
RequestInit
are not implemented. The relevant fields are not present on the
Request
object.- 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-cookie
header is not concatenated when iterated over in the
headers
iterator. 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で標準化されている最中です。