質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

2回答

7387閲覧

APIのリクエストが2重で実行されてしまう

orihime

総合スコア1

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2020/06/14 05:50

JSのクライアントから Goで書かれたAPIサーバにリクエストするようなシステムを作りたいです。

JSクライアントのサーバとGoのAPIサーバは別で実行されていることを想定しています。

以下のような簡単な GoのAPIサーバをローカルの8080ポートで動かしてます。

package main import ( "fmt" "log" "net/http" ) func handle(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Headers", "Content-Type") fmt.Println("aaa") w.WriteHeader(http.StatusOK) fmt.Fprint(w, "SUCCESS") } func main() { http.HandleFunc("/", handle) log.Fatal(http.ListenAndServe(":8080", nil)) }

ここで別の ローカルポート 3000 で動かしている JSクライアントからサーバにPOSTを実行します。

fetch( "http://localhost:8080/", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({"test": 1}) )

上記を実行すると、APIサーバの方の標準出力には aaa が2回表示されます。
これは JSのコードが2回実行されているわけではなく、上記をコンソールから実行しても 2重で実行してしまうようです。
ブラウザの開発者ツールのネットワーク情報を見たところリクエストは1回しか発行されていないので、サーバ側の問題かもしれないとは思っています。

こちらの再現方法ですが、 headers の中身を空にすると問題なく 1回しか実行されないようです。
また、サーバ側からヘッダーの中身を見てみると、1回目は Content-Type が渡ってきておらず 2回目に Content-Type が入ったヘッダーのリクエストが実行されているようでした。

こちらが2重実行してしまう原因を、ご存知の方いらっしゃいませんでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Goのソースは1回しか出力しないように見えますので、おそらくpreflight request分かなと思います。

<参考>
https://qiita.com/nnishimura/items/1f156f05b26a5bce3672

handle内でHTTPメソッドを確認してみると詳細が分かるかと。

<参考> POSTメソッドのみに対応
https://www.yoheim.net/blog.php?q=20170403#t7

投稿2020/06/14 06:12

nabenabe11234

総合スコア126

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

orihime

2020/06/14 07:16

preflight のことを、あまり認識していませんでした。 意識しなくても勝手にやってくれるものだと思っていました。 `Access-Control-Allow-Headers` で `X-Csrftoken` を許可して( preflight に必要そう)、 `Access-Control-Allow-Methods` で `POST` を許可したら preflight が思った通りの動作をするようになりました。 2回処理してしまう部分は、とりあえず `r.Method == http.MethodOptions` を return して対応すると避けれましたが、これが良いのかはもう少し調べてみます。 ありがとうございました。
guest

0

fetchするならFormDataの方が直感的では?

javascript

1const url="http://localhost:8080/"; 2const method="POST"; 3const body= new FormData(); 4body.append("test",1); 5fetch(url,{method,body}).then(res=>res.text()).then(console.log);

投稿2020/06/14 06:25

yambejp

総合スコア114784

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問