👋

[Deno]fetchの使い方について

2022/11/28に公開

fetchの使い方について

前回の記事でfetchの動作不明を書いたが、もともとはStackOverflowのHttp Client using HTTP POST in Denoの下記サンプルでヘッダ指定してあったので参考にコードを書いた。すると、エラー応答になり、ヘッダ指定なしに変更すると、HTTP要求が成功するという問題だった。

    // deno run --allow-net http_client_post.ts
    const form = new FormData();
    form.append("field1", "value1");
    form.append("field2", "value2");
    const response = await fetch("http://localhost:8080", {
        method: "POST",
        headers: { "Content-Type": "multipart/form-data" },
        body: form 
    });
    
    console.log(response)

なお確認環境は次のとおり、

deno 1.26.0 (release, aarch64-unknown-linux-gnu)
v8 10.7.193.3
typescript 4.8.3

この問題の原因を探るため、Python3: http.server のみでデバッグ用の HTTP サーバを作るを参考にサーバを立てて比較したところ次のようになった。

1.ヘッダ指定ありの場合
コード:

    const response = await fetch("http://localhost:8080", {
        method: "POST",
        headers: { "Content-Type": "multipart/form-data" },
        body: form 
    });

リクエスト内容:

content-type: multipart/form-data

2.ヘッダ指定なしの場合
コード:

    const response = await fetch("http://localhost:8080", {
        method: "POST",
        body: form 
    });

リクエスト内容:

content-type: multipart/form-data; boundary=----1073156628018440230470989039

うまく動く場合はboundaryディレクティブが設定されている。RFC 2046によれば、

The Content-Type field for multipart entities requires one parameter, "boundary".

おそらく、内部的にはboundaryを設定しても、headers:で上書きされてしまうため、boundaryなしで送信されてしまうことが問題と思われる。Denoの問題というよりは使い方の問題ですね。

Discussion