代码之家  ›  专栏  ›  技术社区  ›  Bussiere

如何在golang中接收jsonp请求

  •  0
  • Bussiere  · 技术社区  · 7 年前

    console.log(data.location.lng);
    console.log(data.location.lat);
    console.log(data.accuracy);
    var urlgr = "http://127.0.0.1:9220/geo/rec_geo/";
    var pfg = {
        //lo: data.location.lng,
        lo: 1.0,
        //la: data.location.lat,
        la: 2.0,
        //ac: data.accuracy,
        ac: 3,
    };
    $.ajax({
        type: 'GET',
        url: urlgr,
        crossDomain: true,
        data: JSON.stringify(pfg),
        dataType: 'jsonp',
        contentType: "application/json; charset=utf-8",
        success: function (data) {
            console.log("data rec geo");
            console.log(data);
    
        }
    });
    

    type geoData struct {
        Long float32 `json:"lo"`
        Lat   float32  `json:"la"`
        Accuracy  int `json:"ac"`
    }
    
    func recordGeo(w http.ResponseWriter, r *http.Request) {
        s := strings.Split(r.RemoteAddr, ":")
        ip := s[0]
        Info.Println("4")
        var geoRec geoData
        decoder := json.NewDecoder(r.Body)
        err := decoder.Decode(&geoRec)
        fmt.Println("geoRec")
        fmt.Println(geoRec)
        checkErr(err)
    }
    

    但我有一个EOF错误:

    2017/07/01 07:16:22 http: panic serving 127.0.0.1:50680: EOF
    

    所以我的问题是如何在golang中正确接收jsonp请求并将其解析为结构?

    这是我在golang服务器端收到的请求:

    GET /geo/rec_geo/?callback=jQuery31108538596418163691_1498913991164&{%22lo%22:1,%22la%22:2,%22ac%22:3}&_=1498913991166 HTTP/1.1
    Host: 127.0.0.1:9220
    user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
    accept-encoding: gzip, deflate, sdch, br
    accept-language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
    referer: http://localhost:8080/
    cookie: csrftoken=Y7WA181u22l9sScw9UbPxM38wCGQzjaLMMysAesJSWZm89Pj6CCdBkEF01ibpUjW
    alexatoolbar-alx_ns_ph: AlexaToolbar/alx-4.0.1
    connection: keep-alive
    

    信息。打印线路 但我还是有同样的错误

    3 回复  |  直到 7 年前
        1
  •  1
  •   putu    7 年前

    您的 golang 代码,以下行:

    decoder := json.NewDecoder(r.Body)
    Info.Println(r.Body)
    err := decoder.Decode(&geoRec)
    

    Info.Println decoder.Decode 从请求主体读取,请求主体是 io.Reader 打印信息 EOF 状态从这一点上说 Read 将导致 EOF ,您将能够将数据解码到结构。


    我忘了,没有注意到JSONP是 GET

    //snippet inside recordGeo function
    //...
    
    callback := ""
    geoRec := geoData{}
    queries := r.URL.Query()
    
    //See http://api.jquery.com/jQuery.ajax/
    //for 'jsonp' data type parameters.
    for key, val := range queries {
        if key == "callback" {
            callback = val[0]
        } else if key == "_" {
            //the Timestamp
        } else {
            //JSON data in the key
            dec := json.NewDecoder(bytes.NewBufferString(key))
            err := dec.Decode(&geoRec)
            if err != nil {
                log.Println(err)
            }
            log.Printf("DATA=%#v", geoRec)
        }
    }
    
    //...
    //do some processing
    response := "{YOUR RESPONSE DATA}"
    if callback != "" {
        w.Header().Set("Content-Type", "application/javascript")
        response = fmt.Sprintf("%s(%s);", callback, response)
    }
    w.Write([]byte(response))
    

    如果在客户端,您将数据设置为 data: pfg (无 JSON.stringify ),然后在服务器端,可以通过查询参数访问每个参数:

    //
    lon := queries.Get("lo")
    lat := queries.Get("la")
    acc := queries.Get("ac")
    

    或者,如果将AJAX请求数据设置为 data: "mydata=" + JSON.stringify(pfg) ,则可以将数据提取为:

    mydata := queries.Get("mydata")
    dec := json.NewDecoder(bytes.NewBufferString(mydata))
    err := dec.Decode(&geoRec)
    

    处理后,您需要向客户机发送适当的JSONP响应,即。 callback(DATA); .

        2
  •  1
  •   jeevatkm    7 年前

    JSONP 是从服务器接收数据,而不是相反。

    Wikipedia , SO Post JSONP examples

    实际上,它不是特定于Go语言的,您可以在任何服务器端编程中实现JSONP处理。


    出于您的目的,似乎需要来自JavaScript/Jquery的JSON Post请求。然后继续做-

    func recordGeo(w http.ResponseWriter, req *http.Request) {
        decoder := json.NewDecoder(req.Body)
        var geoRec geoData
        if err := decoder.Decode(&geoRec); err != nil {
            fmt.Println(err)
        }
        defer req.Body.Close()
        fmt.Println(geoRec)
    }
    
        3
  •  1
  •   Zalberth    6 年前

    github.com/labstack/echo 包及其中间件),可以完美地处理jsonp请求。这是演示, cook for jsonp