golang使用net/http常见方式

在使用golang的net/http发送http请求的时候,碰到了不少问题,总结了http的常见使用方式

json格式传参

优点:传参方式用json,代码简洁
缺点:Content-Type为application/json发送,php中获取不到post数据,只能从输入流获取;不能设置request的header信息

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
)

func main () {
    path := "http://test.com"
    values := map[string]string{"username":"username","passwd":"passwd"}
    jsonvalue, _ := json.Marshal(values)
    resp,err := http.Post(path, "application/json", bytes.NewBuffer(jsonvalue))
    defer  resp.Body.Close()

    respBody,_:=ioutil.ReadAll(resp.Body)
    fmt.Println(string(respBody), err)
}
//$_POST['username']获取不到;只能file_get_contents("php://input")

postform模拟表单

优点:php中能获取post数据,代码简洁
缺点:不能设置request的header信息

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
    "os"
)

func main() {
    UserName := "username"
    PassWD := "passwd"

    v := url.Values{}
    v.Set("username", UserName)
    v.Set("password", PassWD)

    resp, err := http.PostForm("http://test.com", v)
    if err != nil {
        fmt.Println("Fatal error ", err.Error())
    }
    defer resp.Body.Close()

    content, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("Fatal error ", err.Error())
    }

    fmt.Println(string(content))
}

request方式

优点:能设置header
缺点:代码稍微复杂

发送普通post请求示例

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    Params := map[string]string{
        "is_init"           : "1",
        "name"              : "a.mp4",
        "size"              : "111",
    }

    body, _ := json.Marshal(Params)

    client := &http.Client{}//客户端,被Get,Head以及Post使用
    reqest, err := http.NewRequest("POST", "http://test.com", bytes.NewBuffer(body))
    fmt.Println(Params, body, bytes.NewBuffer(body))
    if err != nil {
        fmt.Println("Fatal error ", err.Error())
    }

    reqest.Header.Set("Content-Type", "application/json") //必须设定该参数,POST参数才能正常提交

    resp, err := client.Do(reqest)//发送请求
    defer resp.Body.Close()//一定要关闭resp.Body
    content, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("Fatal error ", err.Error())
    }

    fmt.Println(string(content))
}

设置request的header信息示例

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
    "strings"
)

func main () {
    v := url.Values{}
    v.Set("name", "name")
    v.Set("is_init", "1")

    body := ioutil.NopCloser(strings.NewReader(v.Encode()))
    client := &http.Client{}//客户端,被Get,Head以及Post使用
    reqest, err := http.NewRequest("POST", "http://test.com", body)

    if err != nil {
        fmt.Println("Fatal error ", err.Error())
    }

    reqest.Header.Set("Content-Type", "application/x-www-form-urlencoded;param=value") //必须设定该参数,POST参数才能正常提交
    reqest.Header.Set("test", "hello")//设置header

    resp, err := client.Do(reqest)//发送请求
    defer resp.Body.Close()//一定要关闭resp.Body
    content, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("Fatal error ", err.Error())
    }

    fmt.Println("response=>", string(content))
}

普通上传图片

package main

import (
    "bytes"
    "fmt"
    "io"
    "io/ioutil"
    "mime/multipart"
    "net/http"
    "os"
)

func main() {
    Upload("http://test.com/upload", "/tmp/upload.png");
}

func  Upload(request_url, file_path string) {
    file, err := os.Open(file_path)
    if err != nil {
        fmt.Println("error opening file")
    }

    defer file.Close()
    //创建一个模拟的form中
    bodyBuf := &bytes.Buffer{}
    bodyWriter := multipart.NewWriter(bodyBuf)

    //通过$_FILE['file']获取
    fileWriter, err := bodyWriter.CreateFormFile("file", file_path)
    if err != nil {
        fmt.Println("error writing to buffer")
    }

    //这里相当于选择了文件,将文件放到form中
    _, err = io.Copy(fileWriter, file)
    if err != nil {
        fmt.Println("Fatal error ", err.Error())
    }

    //获取上传文件的类型,multipart/form-data; boundary=...
    contentType := bodyWriter.FormDataContentType()

    //这个很关键,必须这样写关闭,不能使用defer关闭,不然会导致错误
    bodyWriter.Close()

    //上传的其他参数设置
    params := map[string]string{
        "desc": "这里可以传入别的参数",
    }

    for key, val := range params {
        _ = bodyWriter.WriteField(key, val)
    }

    resp, err := http.Post(request_url, contentType, bodyBuf)
    if err != nil {
        fmt.Println("error writing to buffer")
    }

    defer resp.Body.Close()
    resp_body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("error writing to buffer")
    }

    fmt.Println(string(resp_body))
}

上传图片,并设置header

package main

import (
    "bytes"
    "fmt"
    "io"
    "io/ioutil"
    "log"
    "mime/multipart"
    "net/http"
    "os"
    "path/filepath"
)

func main() {
    Upload("http://test.com/upload", "/tmp/upload.png", "this is code")
}

func Upload(request_url, img_path, code string) {
    file, err := os.Open(img_path)
    if err != nil {
        fmt.Println(err.Error())
    }
    defer file.Close()

    body := &bytes.Buffer{}
    writer := multipart.NewWriter(body)
    //通过$_FILE['common']获取
    part, err := writer.CreateFormFile("common", filepath.Base(img_path))
    if err != nil {
        fmt.Println(err.Error())
    }
    _, err = io.Copy(part, file)

    err = writer.Close()
    if err != nil {
        fmt.Println(err.Error())
    }

    req, err := http.NewRequest("POST", request_url, body)
    req.Header.Set("Content-Type", writer.FormDataContentType())
    //业务需要进行auth,通过$_SERVER['HTTP_AUTHORIZATION']获取
    req.Header.Set("authorization", "Bearer "+code)

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    }

    content, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }

    resp.Body.Close()

    fmt.Println(string(content))
}

以上是常见的几种方式,在使用过程中,可以把request的方式再封装一层,简化代码再调用
「注:封装的不是很好,可以按照自己的需求来」

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
    "strings"
)

func main () {
    params := map[string]string{
        "name": "name",
        "is_init":"1",
    }

    headers := map[string]string{
        "Content-Type" : "application/x-www-form-urlencoded;param=value",
    }

    Http("http://test.com", params, headers)
}

func Http(request_url string, params map[string]string, header map[string]string) string {
    v := url.Values{}
    for key, val := range params {
        v.Set(key, val)
    }

    body := ioutil.NopCloser(strings.NewReader(v.Encode()))
    client := &http.Client{}
    reqest, err := http.NewRequest("POST", request_url, body)

    if err != nil {
        fmt.Println("Fatal error ", err.Error())
    }

    for key, val := range header {
        reqest.Header.Set(key, val)
    }

    resp, err := client.Do(reqest)
    defer resp.Body.Close()
    content, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("Fatal error ", err.Error())
    }

    fmt.Println(string(content))
    return string(content)
}

 

—— END ——

文 | SunnySmileZ (转载请注明出处)

微信号:zhouzhi1229

github:github.com/SunnySmilez

喜欢我、想第一时间读我,你可以扫描二维码关注我

640?wx_fmt=jpeg

转载于:https://my.oschina.net/u/1383733/blog/2885274

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值