JSON形式かx-www-form-urlencoded形式かで、実装方法が異なるみたいです。
バージョン
axios 0.24.0
go 1.16.6
react ^17.0.2
それぞれの違い
x-www-form-urlencoded形式
Content-Type ・・・ application/x-www-form-urlencoded
例 ・・・ a=1&b=1(エンコード後:%20a%3D1%26b%3D1)
Go(サーバー側)の実装の際にr.Form.Get("name")、r.FormValue("name")、r.PostFormValue("name")のメソッドで送信されたデータを取り出せる。multipart/form-data形式もGoの実装方法は同じだが、key-value型のデータを送るのでapplication/x-www-form-urlencoded形式を使うことにする。
JSON形式
Content-Type ・・・ application/json
例 ・・・ {“a”:1,”b”:2}
Go(サーバー側)の実装の際に送信されたデータをデコードしてから取り出さなくてはならない。また、CORSの規定によりプリフライトが飛ぶので、ヘッダーに"Access-Control-Allow-Headers"と"Access-Control-Allow-Methods"を指定する必要がある。
実装例
x-www-form-urlencoded形式
import axios from "axios";
const App = () => {
const handleSubmit = (event) => {
event.preventDefault();
// multipart/form-data形式のデータをapplication/x-www-form-urlencodedに変換
const params = new URLSearchParams(new FormData(event.currentTarget));
axios.post("http://localhost:8080", params);
};
return (
<form onSubmit={(event) => handleSubmit(event)}>
<label htmlFor="name">Name: </label>
<br />
<input type="text" id="name" name="name" />
<br />
<input type="submit" defaultValue={"Submit"} />
</form>
);
};
export default App;
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
h := func(w http.ResponseWriter, r *http.Request) {
// オリジンが違う場合は設定する
w.Header().Add("Access-Control-Allow-Origin", "http://localhost:3000")
// FormValueメソッドで値を取り出せる
fmt.Println("Name:", r.FormValue("name"))
}
http.HandleFunc("/", h)
log.Fatal(http.ListenAndServe(":8080", nil))
}
JSON形式
import axios from "axios";
const App = () => {
const handleSubmit = event => {
event.preventDefault();
const data = new FormData(event.currentTarget);
axios.post('http://localhost:8080', {
// axiosならJSONデータをリテラルで書ける
name: data.get("name")
})
};
return (
<form onSubmit={event => handleSubmit(event)}>
<label htmlFor="name">Name: </label>
<br/>
<input type="text" id="name" name="name"/>
<br/>
<input type="submit" defaultValue={"Submit"}/>
</form>
);
}
export default App;
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
type Param struct {
// jsonで型定義
Name string `json:"name"`
}
func main() {
h := func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")
// プリフライト用。Content-Type(application/json含む)のヘッダーのリクエストを許可する。
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
// プリフライト用。POSTメソッドのリクエストを許可する。
w.Header().Set("Access-Control-Allow-Methods", "POST")
if r.Method == "POST" {
// 変数を定義
var param Param
// デコードして変数へ値を格納する
if err := json.NewDecoder(r.Body).Decode(¶m); err != nil {
log.Fatal(err)
}
fmt.Println("Name:", param.Name)
}
}
http.HandleFunc("/", h)
log.Fatal(http.ListenAndServe(":8080", nil))
}
感想
x-www-form-urlencoded形式の方が実装が少し楽だけど、こっちでいいのかな・・・