Golang HTTPリクエスト

設定要求
応答モードでの相互作用のHTTPリクエストとレスポンス。私たちが見ているだろう要求、2番目のパラメータhttp.Requestsハンドラ機能を行きます。その構造は次のとおりです。

type Request struct {
    Method string

    URL *url.URL
    Proto      string // "HTTP/1.0"
    ProtoMajor int    // 1
    ProtoMinor int    // 0
    Header Header
    Body io.ReadCloser
    ContentLength int64
    TransferEncoding []string
    Close bool
    Host string
    Form url.Values
    PostForm url.Values
    MultipartForm *multipart.Form
  ....
    ctx context.Context
}

あなたは、基本的な情報は、すべてのHTTPリクエストを包含し、要求の構造から見ることができます。要求、要求されたURL、メソッド、ヘッダー、これらの構造のボディについての主な関心事のために。

URL
HTTP URL形式手法への要求:// [userinfoを@]ホスト /パス[#fragment]、ゴーは、 HTTPリクエストURL [?クエリ]をマッピングするために使用されるURLの構造を、提供します。

type URL struct {
  Scheme   string
  Opaque   string
  User     *Userinfo
  Host     string
  Path     string
  RawQuery string
  Fragment string
}

URLの形式は、実際に、それはより良い用語URI、ユニフォームリソースロケータである必要があり、比較的明確です。より重要なURLクエリ文字列クエリです。通常のGETリクエストのパラメータとして。符号分割&KEY1 =値1&KEY2 = value2のキーと値のペアを使用して、いくつかのクエリ、URLはASSICコーディングコード、およびクエリでurlencode用従って必要であるからです。request.URI.RawQueryで読み取り、クエリを行きます

func indexHandler(w http.ResponseWriter, r *http.Request) {
    info := fmt.Sprintln("URL", r.URL, "HOST", r.Host, "Method", r.Method, "RequestURL", r.RequestURI, "RawQuery", r.URL.RawQuery)
    fmt.Fprintln(w, info)
}

☁  ~  curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'name=vanyar&age=27' "http://127.0.0.1:8000?lang=zh&version=1.1.0"
URL /?lang=zh&version=1.1.0 HOST 127.0.0.1:8000 Method POST RequestURL /?lang=zh&version=1.1.0 RawQuery lang=zh&version=1.1.0

ヘッダ
、ヘッダHTTPの重要な部分。リクエストヘッダ構造は、構造を有し、ヘッダは、本質的にマップ(マップ[文字列] []の文字列)。図マップとしてキー値のHTTPプロトコル・ヘッダ:

    Host: example.com
    accept-encoding: gzip, deflate
    Accept-Language: en-us
    fOO: Bar
    foo: two


    Header = map[string][]string{
        "Accept-Encoding": {"gzip, deflate"},
        "Accept-Language": {"en-us"},
        "Foo": {"Bar", "two"},
    }

ヘッダフィールドは、多くの場合、コンテンツタイプを指定して要求し、通信設定の多くが含まれています。

func indexHandler(w http.ResponseWriter, r *http.Request) {
 
    info := fmt.Sprintln(r.Header.Get("Content-Type"))
    fmt.Fprintln(w, info)
}

☁  ~  curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'name=vanyar&age=27' "http://127.0.0.1:8000?lang=zh&version=1.1.0"

ファイルアプリケーション/ x-www-form-urlencodedで
Golng印刷は基本的に3つのカテゴリー3分割、多くの機能を提供します。printlnとのprintfを印刷しておくこと。
、比較的単純な印刷標準出力ストリームに印刷され、printlnのマルチプリント改行ことを除いて同じ。printfの書式文字列が印刷されるように、この方法は、3バイトの印刷の数を返します。スプリントは、Sprinln sprintfの文字列と印刷はありません標準出力ストリームに、返されます。FPRINT、このオブジェクトにio.Writer、HTTPインタフェース出力を置く関数fprintf Fprinln印刷がhttp.ReponseWriterある結果、印刷枚数バイトに戻ります。

ボディ
本体を介して送信されたHTTPデータ通信、。ReadCloserインタフェースであるパッケージ本体ボディリクエスト、に入ります。リーダインタフェースメソッドは、Read(P []バイト)(持つインターフェースである N INT、ERRエラー) このようにバイト配列を読み取ることによって、要求されたデータ缶体を得る、方法。

func indexHandler(w http.ResponseWriter, r *http.Request) {

    info := fmt.Sprintln(r.Header.Get("Content-Type"))
    len := r.ContentLength
    body := make([]byte, len)
    r.Body.Read(body)
    fmt.Fprintln(w, info, string(body))
}

☁  ~  curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'name=vanyar&age=27' "http://127.0.0.1:8000?lang=zh&version=1.1.0"
application/x-www-form-urlencoded
 name=vanyar&age=27
可见,当请求的content-type为application/x-www-form-urlencoded, body也是和query一样的格式,key-value的键值对。换成json的请求方式则如下:

☁  ~  curl -X POST -H "Content-Type: application/json" -d '{name: "vanyar", age: 27}' "http://127.0.0.1:8000?lang=zh&version=1.1.0"
application/json
 {name: "vanyar", age: 27}
multipart/form-data的格式用来上传图片,请求的body如下:

☁  ~  curl -X POST -H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" -F "name=vanyar" -F "age=27" "http://127.0.0.1:8000?lang=zh&version=1.1.0"
multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW; boundary=------------------------d07972c7800e4c23
 --------------------------d07972c7800e4c23
Content-Disposition: form-data; name="name"

vanyar
--------------------------d07972c7800e4c23
Content-Disposition: form-data; name="age"

27
--------------------------d07972c7800e4c23--

フォーム
の解析体は、クライアントによって要求されたデータを読み取ることができます。そして、このデータは、より原始的であるかどうかまたはフォーム・データのデータへの鍵です。読む直接非常に面倒に解決。ボディは通常、提供されたデータを形成します。したがって、これらのゴーフォームデータを処理する方法を提供します。

Form1の
移動は、提供されたデータ分析ParseFormフォーム、X-WWW-フォームでurlencodeデータ、すなわち、コンテンツ・タイプのための方法を提供します。

func indexHandler(w http.ResponseWriter, r *http.Request) {

    contentType := fmt.Sprintln(r.Header.Get("Content-Type"))

    r.ParseForm()
    fromData := fmt.Sprintf("%#v", r.Form)
    fmt.Fprintf(w, contentType, fromData)

}

☁  ~  curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'name=vanyar&age=27' "http://127.0.0.1:8000?lang=zh&version=1.1.0"
application/x-www-form-urlencoded
%!(EXTRA string=url.Values{"name":[]string{"vanyar"}, "age":[]string{"27"}, "lang":[]string{"zh"}, "version":[]string{"1.1.0"}})%

データ構造とを読み取るための方法は、一般的に、いくつか以下があります。

    fmt.Println(r.Form["lang"])
    fmt.Println(r.PostForm["lang"])
    fmt.Println(r.FormValue("lang"))
    fmt.Println(r.PostFormValue("lang"))

ParseFormを呼び出した後でなければなりませんR.Formとr.PostFormは、我々はそれ以外の場合は空の配列で、データを持っています。
必要性のParseFormなしコールr.FormValueとr.PostFormValue(「LANG」)は、データを読み取ることができます。

さらにr.Formとr.PostFormアレイ構造であるが、同じ名前のURLのパラメータは、体内に存在すると、r.Formアレイと接頭POSTで、二つの値、すなわち[「EN」、「ZHを」]有しこの方法では、データは本体のみを読み取ることができます。

☁  ~  curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'name=vanyar&age=27&lang=en' "http://127.0.0.1:8000?lang=zh&version=1.1.0"
application/x-www-form-urlencoded
%!(EXTRA string=url.Values{"version":[]string{"1.1.0"}, "name":[]string{"vanyar"}, "age":[]string{"27"}, "lang":[]string{"en", "zh"}})%

あなたが見ることができる。この時点で、LANGパラメータだけでなく、ポストの体も提供しては、デフォルトの優先度データのボディに行くURLクエリ、両方のデータを持って提供し、カバーしません。

あなたは、URLパラメータ、またはコールPostForm値を読みたくない場合はPostFormValueフィールドを読み取ることができます。

r.PostForm["lang"][0]
r.PostFormValue["lang"]
对于form-data的格式的数据,ParseForm的方法只会解析url中的参数,并不会解析body中的参数。

☁  ~  curl -X POST -H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" -F "name=vanyar" -F "age=27" -F "lang=en" "http://127.0.0.1:8000?lang=zh&version=1.1.0"
multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW; boundary=------------------------5f87d5bfa764488d
%!(EXTRA string=url.Values{"lang":[]string{"zh"}, "version":[]string{"1.1.0"}}
)%

そうでない場合r.Fromは体の内容を読んでいないときに、フォームデータ要求のコンテンツタイプを使用すると、MutilpartFromを変更する必要がある場合、ParseFrom、したがって、あなただけのクエリ文字列の内容を読み取ることができます。

MutilpartFrom
ParseMutilpartFromメソッドは、パラメータの読み取りデータ長を提供伴い、その後、フォームデータを読み取る同じ方法を使用し、MutilpartFrom本体はデータのみを読み込み、データのクエリは、URLを読み取れません。

func indexHandler(w http.ResponseWriter, r *http.Request) {
    r.ParseMultipartForm(1024)

    fmt.Println(r.Form["lang"])
    fmt.Println(r.PostForm["lang"])
    fmt.Println(r.FormValue("lang"))
    fmt.Println(r.PostFormValue("lang"))
    fmt.Println(r.MultipartForm.Value["lang"])

    fmt.Fprintln(w, r.MultipartForm.Value)
}

戻る[名前を:[ヴァンヤール]年齢:[27]のlang:[EN]]は、マップ要求の後見ることができます。それr.MultipartForm.Valueと、URLのパラメータなし。

要約すると、読み出しでurlencodeエンコーディング、ParseFormのみメソッドをコードするフォームデータを読み取るために必要ParseMultipartFormの使用を必要とします。両方のパラメータがURL場合は、別のボディから、及び場合、fromValue方法を読み取ることができます。ポスト接頭辞方法は、本体のみのデータ内容を読み取ることができます。前記データは、MultipartForm r.MultipartForm.Valueのアクセスを得ました。

ファイルアップロード
フォームデータ形式最も使用方法は、時間の写真をアップロードすることです。r.MultipartForm.Valueはフィールドデータポストのボディで、r.MultipartForm.Fileは、画像データが含まれています。

func indexHandler(w http.ResponseWriter, r *http.Request) {

    r.ParseMultipartForm(1024)
    fileHeader := r.MultipartForm.File["file"][0]
    fmt.Println(fileHeader)
    file, err := fileHeader.Open()
    if err == nil{
        data, err := ioutil.ReadAll(file)
        if err == nil{
            fmt.Println(len(data))
            fmt.Fprintln(w, string(data))
        }
    }
    fmt.Println(err)
}

リクエストを発行した後、あなたは返すの画像を見ることができます。もちろん、より良いツールがr.FormFile、アップロードファイルを直接読み込んだデータを機能提供して行きます。ParseMultipartFormメソッドを使用する必要はありません。

    file, _, err := r.FormFile("file")

    if err == nil{
        data, err := ioutil.ReadAll(file)
        if err == nil{
            fmt.Println(len(data))
            fmt.Fprintln(w, string(data))
        }
    }
    fmt.Println(err)

NOの場合、他のフィールドそれでもLANGパラメータ、またはParseMultipartForm呼び出しを追加する必要が読む必要がある場合にのみ、ケースファイルのフィールドに適用されます。ファイルをアップロードするために読んで、次のステップは、動作するために非常に一般的なIO書き込みファイルがあります。

JSONは
、分離の終わり頃、今通常、JSON形式に慣れていくつかのフレームワークによって提出されたクライアントデータの上昇、角度、VUE、反応し、人気があります。JSON形式の場合は、身体のJSON文字列は、ネイティブです。つまり、の行くJSONデータ構造を解読するために行きます。

type Person struct {
    Name string
    Age int
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
    decode := json.NewDecoder(r.Body)
    var p Person
    err := decode.Decode(&p)
    if err != nil{
        log.Fatalln(err)
    }
    info := fmt.Sprintf("%T\n%#v\n", p, p)
    fmt.Fprintln(w, info)
}

☁  ~  curl -X POST -H "Content-Type: application/json"  -d '{"name": "vanyar", "age": 27 }' "http://127.0.0.1:8000?lang=zh&version=1.1.0"
main.Person
main.Person{Name:"vanyar", Age:27}

JSONの詳細については、ずっと後の議論。詳細については、公式サイトのドキュメントを参照してください。

応答
要求と応答は、同様のメッセージ・フォーマット、関連するプロセスと構造が類似している彼らだけではなく、双子の兄弟、httpです。ゴー構造は、応答ResponseWriterインターフェイスで構成されています。

type ResponseWriter interface {
    Header() Header
    Write([]byte) (int, error)
    WriteHeader(int)
}

この方法は非常に簡単である内部ヘッダ方法は、ヘッダ構造のマップを返します。WriteHeader応答ステータスコードが返されます。クライアントデータへの書き込みバック。

私たちは、データがW応答に直接書き込まれ、fmt.Fprintlnメソッドを使用しています。また、メソッドの戻りを書く文字を呼び出すことができます。


func indexHandler(w http.ResponseWriter, r *http.Request) {
    str := `<html>
<head><title>Go Web Programming</title></head>
<body><h1>Hello World</h1></body>
</html>`
    w.Write([]byte(str))
}

☁  ~  curl -i http://127.0.0.1:8000/
HTTP/1.1 200 OK
Date: Wed, 07 Dec 2016 09:13:04 GMT
Content-Length: 95
Content-Type: text/html; charset=utf-8

<html>
<head><title>Go Web Programming</title></head>
<body><h1>Hello World</h1></body>
</html>%     
                                                                             ☁  ~
go根据返回的字符,自动修改成了text/html的Content-Type格式。返回数据自定义通常需要修改header相关信息。

func indexHandler(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(501)
    fmt.Fprintln(w, "No such service, try next door")
}


☁  ~  curl -i http://127.0.0.1:8000/
HTTP/1.1 501 Not Implemented
Date: Wed, 07 Dec 2016 09:14:58 GMT
Content-Length: 31
Content-Type: text/plain; charset=utf-8

No such service, try next door

リダイレクト
リダイレクト機能を達成するための場所とHTTPヘッダのステータスコードを設定します。

func indexHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Location", "https://google.com")
    w.WriteHeader(302)
}

☁  ~  curl -i http://127.0.0.1:8000/
HTTP/1.1 302 Found
Location: https://google.com
Date: Wed, 07 Dec 2016 09:20:19 GMT
Content-Length: 31
Content-Type: text/plain; charset=utf-8
重定向是常用的功能,因此go也提供了工具方法,http.Redirect(w, r, "https://google.com", http.StatusFound)。

リクエストヘッダ構造と同様に、w.Headerヘッダを設定するには、いくつかの方法があります

func (h Header) Add(key, value string) {
    textproto.MIMEHeader(h).Add(key, value)
}

func (h Header) Set(key, value string) {
    textproto.MIMEHeader(h).Set(key, value)
}

func (h MIMEHeader) Add(key, value string) {
    key = CanonicalMIMEHeaderKey(key)
    h[key] = append(h[key], value)
}

func (h MIMEHeader) Set(key, value string) {
    h[CanonicalMIMEHeaderKey(key)] = []string{value}
}

セットと方法を追加し、既存のキーのために、セットヘッダすることができ、追加の値の配列を追加し,,設定した値は、値のための直接交換です。それAPPENDと割り当ての違い。

JSONの
データ要求は、同じデータに応答してもJSONであってもよい、JSONであってもよいです。安らかなスタイルのAPI JSON形式のデータが返されます。JSON文字列要求は応答がJSON文字列をエンコードされ、デコードされ、Goが標準ライブラリのエンコーディング/ JSONを提供します

type Post struct {
    User string
    Threads []string
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    post := &Post{
        User: "vanyar",
        Threads: []string{"first", "second", "third"},
    }
    json, _ := json.Marshal(post)
    w.Write(json)
}

☁  ~  curl -i http://127.0.0.1:8000/
HTTP/1.1 200 OK
Content-Type: application/json
Date: Thu, 08 Dec 2016 06:45:17 GMT
Content-Length: 54

{"User":"vanyar","Threads":["first","second","third"]}%

もちろん、契約の詳細は後にこれを行うJSON。

概要
Webアプリケーションのためには、応答は、基本的な内容に返され、要求を処理します。golangもリクエストをカプセル化し、ReponseWriterを開発することでした。要求又は応答するかどうか、URL、ヘッダとボディ関連のデータのために処理されます。httpプロトコルの基本的な内容。

体を処理し、時々、ヘッダ内のプロセスデータに必要なデータに加えて、一般的な例は、治療クッキーです。このトピックでは、クッキーに説明します。

おすすめ

転載: www.cnblogs.com/enumx/p/12330526.html