3
1

More than 1 year has passed since last update.

React+axiosでPOST送信したデータをGoで受け取る

Last updated at Posted at 2021-12-27

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(&param); err != nil {
                log.Fatal(err)
            }
            fmt.Println("Name:", param.Name)
        }
    }

    http.HandleFunc("/", h)

    log.Fatal(http.ListenAndServe(":8080", nil))
}

感想

x-www-form-urlencoded形式の方が実装が少し楽だけど、こっちでいいのかな・・・

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1