【问题标题】:Request body empty after posting data to endpoint将数据发布到端点后请求正文为空
【发布时间】:2019-09-17 07:13:39
【问题描述】:

我不确定为什么在运行以下 curl 请求时发布的数据不存在:

curl --request POST http://localhost:4000 --header "Content-Type: application/json" --data '{ "hostname": "bbc.co.uk" }'

反对下面的代码。它本质上只是使用变量hostname 发布json,但由于某种原因它没有出现在req.Body 或Domain 结构数组中。请注意这是基于this tutorial

package main

import (
    "encoding/json"
    "log"
    "net/http"
    "fmt"

    "github.com/gorilla/mux"
    "github.com/gorilla/handlers"
)

type Domain struct {
    hostname string   `json:"hostname,omitempty"`
}

var domains []Domain

func CreateDomainEndpoint(w http.ResponseWriter, req *http.Request) {
    var domain Domain

    fmt.Println(req.Body)
    _ = json.NewDecoder(req.Body).Decode(&domain)
    domains = append(domains, domain)
    json.NewEncoder(w).Encode(domains)
}

func main() {
    router := mux.NewRouter()
    router.HandleFunc("/", CreateDomainEndpoint).Methods("POST")

    log.Fatal(http.ListenAndServe(":4000", handlers.CORS(handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type", "Authorization"}), handlers.AllowedMethods([]string{"GET", "POST", "PUT", "HEAD", "OPTIONS"}), handlers.AllowedOrigins([]string{"*"}))(router)))
}

【问题讨论】:

    标签: go gorilla


    【解决方案1】:
    • JSON 编解码器忽略 hostname 字段,因为该字段不是 exported。通过大写字段名称来修复。
    • domains 上存在数据竞争。通过使用mutex 保护对变量的访问来修复。
    • 应用程序忽略错误。通过检查并处理从 JSON 解码器返回的错误进行修复。

    以下是修复代码:

    package main
    
    import (
        "encoding/json"
        "log"
        "net/http"
        "sync"
    
        "github.com/gorilla/handlers"
        "github.com/gorilla/mux"
    )
    
    type Domain struct {
        Hostname string `json:"hostname,omitempty"`
    }
    
    var (
        domains []Domain
        mu      sync.Mutex
    )
    
    func CreateDomainEndpoint(w http.ResponseWriter, req *http.Request) {
        var domain Domain
        if err := json.NewDecoder(req.Body).Decode(&domain); err != nil {
            http.Error(w, "bad request", 400)
            return
        }
        mu.Lock()
        domains = append(domains, domain)
        // To avoid holding the mutex while writing to the
        // response body, make a local copy of the slice header.
        d := domains
        mu.Unlock()
    
        json.NewEncoder(w).Encode(d)
    }
    
    func main() {
        router := mux.NewRouter()
        router.HandleFunc("/", CreateDomainEndpoint).Methods("POST")
    
        log.Fatal(http.ListenAndServe(":4000", handlers.CORS(handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type", "Authorization"}), handlers.AllowedMethods([]string{"GET", "POST", "PUT", "HEAD", "OPTIONS"}), handlers.AllowedOrigins([]string{"*"}))(router)))
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-22
      • 2019-05-02
      • 2022-01-11
      • 2020-04-12
      • 2017-05-23
      • 2020-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多