ในแพ็กเกจ http ของ Go ฉันจะรับสตริงข้อความค้นหาในคำขอ POST ได้อย่างไร


114

ฉันใช้httpแพ็คเกจจาก Go เพื่อจัดการกับคำขอ POST ฉันจะเข้าถึงและแยกวิเคราะห์เนื้อหาของสตริงการสืบค้นจากRequestวัตถุได้อย่างไร ฉันไม่พบคำตอบจากเอกสารอย่างเป็นทางการ


สิ่งหนึ่งที่ควรทราบหากคุณใช้ cURL เพื่อส่งคำขอและคุณใช้r.FormValue("id")เพื่อดึงข้อมูลพารามิเตอร์การค้นหาคุณจะไม่สามารถส่ง i ผ่านข้อมูลแบบฟอร์มใน cURL ได้ (กล่าวคือcurl 0.0.0.0:8888 -d id=foobarจะไม่ทำงาน) คุณต้องส่งผ่านพารามิเตอร์แบบสอบถาม ( curl 0.0.0.0:8888?id=foobar)

คำตอบ:


145

QueryString คือตามคำจำกัดความใน URL คุณสามารถเข้าถึง URL ของคำขอโดยใช้req.URL( doc ) ออบเจ็กต์ URL มีQuery()เมธอด ( doc ) ที่ส่งคืนValuesประเภทซึ่งเป็นเพียงmap[string][]stringพารามิเตอร์ QueryString

หากสิ่งที่คุณกำลังมองหาคือข้อมูล POST ตามที่ส่งมาในรูปแบบ HTMLนี่คือคู่คีย์ - ค่าในเนื้อหาคำขอ (โดยปกติ) คำตอบของคุณถูกต้องว่าคุณสามารถโทรParseForm()แล้วใช้req.Formฟิลด์เพื่อรับแผนที่ของคู่คีย์ - ค่า แต่คุณสามารถเรียกFormValue(key)เพื่อรับค่าของคีย์เฉพาะได้ สิ่งนี้จะเรียกParseForm()ถ้าจำเป็นและรับค่าโดยไม่คำนึงถึงวิธีการส่ง (เช่นในสตริงการสืบค้นหรือในเนื้อหาคำขอ)


2
ขอบคุณสำหรับข้อตกลง
Fabien

2
ฉันพบเมธอด 'req.FormValue (key)' เร็วขึ้นและทำเพื่อคุณทุกรหัสที่จำเป็นเพื่อแยกวิเคราะห์ url ล่วงหน้า
OnlyAngel

6
req.URL.RawQueryส่งคืนทุกอย่างหลังจาก?คำขอ GET หากช่วยได้
kouton

ฉันพบว่ามันน่าสนใจ req.Form คืออาร์เรย์ว่างเว้นแต่จะมีการเรียกใช้ req.formValue ("some_field") ในการเช่าครั้งเดียว
Qian Chen

ขอบคุณมาก! @kouton
Aditya Varma

127

นี่คือตัวอย่างที่ชัดเจนมากขึ้นเกี่ยวกับวิธีเข้าถึงพารามิเตอร์ GET Requestวัตถุจะมีวิธีการที่จะแยกวิเคราะห์พวกเขาออกมาให้คุณเรียกว่าแบบสอบถาม :

สมมติว่าขอ URL เช่นhttp: // host: port / something? param1 = b

func newHandler(w http.ResponseWriter, r *http.Request) {
  fmt.Println("GET params were:", r.URL.Query())

  // if only one expected
  param1 := r.URL.Query().Get("param1")
  if param1 != "" {
    // ... process it, will be the first (only) if multiple were given
    // note: if they pass in like ?param1=&param2= param1 will also be "" :|
  }

  // if multiples possible, or to process empty values like param1 in
  // ?param1=&param2=something
  param1s := r.URL.Query()["param1"]
  if len(param1s) > 0 {
    // ... process them ... or you could just iterate over them without a check
    // this way you can also tell if they passed in the parameter as the empty string
    // it will be an element of the array that is the empty string
  }    
}

นอกจากนี้โปรดทราบว่า "คีย์ในแมปค่า [เช่น Query () return value] นั้นคำนึงถึงตัวพิมพ์เล็กและใหญ่"


4
คำตอบก่อนหน้ากล่าวแล้วและเชื่อมโยงกับเอกสารในการทำเพียงแค่ว่า (และก็ไม่ได้มีตัวอย่างที่จะตื่นตระหนกกับการออกไปจากตัวนักการหั่นอ้างอิงถ้าข้อมูลที่ต้องการไม่อยู่ในการใช้งานr.URL.Query().Get("moviename")เพื่อหลีกเลี่ยงความผิดพลาดร้ายแรงนี้)
Dave C

1
ขอบคุณสำหรับข้อมูล. ใช่เอกสารค่อนข้างสับสนสำหรับฉันดังนั้นฉันจึงโพสต์สิ่งนี้เป็น "มือตัวอย่าง" มากกว่าในกรณีที่มีประโยชน์ แก้ไขการตรวจสอบศูนย์ การใช้Getวิธีนี้จะส่งกลับค่าแรกเท่านั้นหากมีหลายตัวดังนั้นนี่คือตัวอย่างของมากกว่า ข้อมูลที่เป็นประโยชน์ขอขอบคุณ!
rogerdpack

นอกจากนี้ฉันไม่คิดว่าคุณสามารถเปรียบเทียบสตริงกับ nil: devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang ie string! = "" ถูกต้อง
James Milner

ฉันไม่คิดว่าโค้ดนั้นจะรวบรวมได้เป็นตัวอย่างที่สมบูรณ์ คุณไม่สามารถเปรียบเทียบสตริงที่ว่างเปล่าที่กลับมาพร้อมกับ Values.Get() golang.org/pkg/net/url/#Valuesnil
Daniel Farrell

19

ด้านล่างนี้คือตัวอย่าง:

value := r.FormValue("field")

สำหรับข้อมูลเพิ่มเติม เกี่ยวกับแพคเกจ http คุณสามารถเยี่ยมชมเอกสารประกอบที่นี่ FormValueโดยทั่วไปจะส่งคืนค่า POST หรือ PUT หรือ GET ตามลำดับซึ่งเป็นค่าแรกที่พบ


8

นี่คือตัวอย่างการใช้งานง่ายๆ:

package main

import (
    "io"
    "net/http"
)
func queryParamDisplayHandler(res http.ResponseWriter, req *http.Request) {
    io.WriteString(res, "name: "+req.FormValue("name"))
    io.WriteString(res, "\nphone: "+req.FormValue("phone"))
}

func main() {
    http.HandleFunc("/example", func(res http.ResponseWriter, req *http.Request) {
        queryParamDisplayHandler(res, req)
    })
    println("Enter this in your browser:  http://localhost:8080/example?name=jenny&phone=867-5309")
    http.ListenAndServe(":8080", nil)
}

ใส่คำอธิบายภาพที่นี่


6

มีสองวิธีในการรับพารามิเตอร์แบบสอบถาม:

  1. ใช้ reqeust.URL.Query ()
  2. การใช้ request.Form

ในกรณีที่สองเราต้องระมัดระวังเนื่องจากพารามิเตอร์ของร่างกายจะมีความสำคัญเหนือกว่าพารามิเตอร์การค้นหา คำอธิบายแบบเต็มเกี่ยวกับการรับพารามิเตอร์แบบสอบถามสามารถพบได้ที่นี่

https://golangbyexample.com/net-http-package-get-query-params-golang


5

คำด้านล่างมาจากเอกสารอย่างเป็นทางการ

แบบฟอร์มที่มีข้อมูลในแบบฟอร์มแจงรวมทั้งทั้งพารามิเตอร์การค้นหาข้อมูลของ URLและโพสต์หรือข้อมูลในแบบฟอร์ม PUT ฟิลด์นี้จะพร้อมใช้งานหลังจากเรียก ParseForm เท่านั้น

ดังนั้นโค้ดตัวอย่างด้านล่างจะใช้งานได้

func parseRequest(req *http.Request) error {
    var err error

    if err = req.ParseForm(); err != nil {
        log.Error("Error parsing form: %s", err)
        return err
    }

    _ = req.Form.Get("xxx")

    return nil
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.