zoukankan      html  css  js  c++  java
  • golang几种post方式

    用golang进行http请求类型多了,总结备忘一下。

    1.普通的postget请求

       var r http.Request
        r.ParseForm()
        r.Form.Add("uuid", orderUUID)
        bodystr := strings.TrimSpace(r.Form.Encode())
        request, err := http.NewRequest("GET", url, strings.NewReader(bodystr))
        if err != nil {
           //TODO:  
        }
        request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
        request.Header.Set("Connection", "Keep-Alive")
    
        var resp *http.Response
        resp, err = http.DefaultClient.Do(request)
        if err != nil {
        //TODO:
        }

    2. body全部二进制数据流进行post

    //body提交二进制数据
    func DoBytesPost(url string, data []byte) ([]byte, error) {
    
        body := bytes.NewReader(data)
        request, err := http.NewRequest(POST_METHOD, url, body)
        if err != nil {
            log.Println("http.NewRequest,[err=%s][url=%s]", err, url)
            return []byte(""), err
        }
        request.Header.Set("Connection", "Keep-Alive")
        var resp *http.Response
        resp, err = http.DefaultClient.Do(request)
        if err != nil {
            log.Println("http.Do failed,[err=%s][url=%s]", err, url)
            return []byte(""), err
        }
        defer resp.Body.Close()
        b, err := ioutil.ReadAll(resp.Body)
        if err != nil {
            log.Println("http.Do failed,[err=%s][url=%s]", err, url)
        }
        return b, err
    }

    3. 模拟web表单文件上传进行post

    func newfileUploadRequest(uri string, params map[string]string, paramName, path string) (*http.Request, error) {
        file, err := os.Open(path)
        if err != nil {
            return nil, err
        }
        defer file.Close()
    
        body := &bytes.Buffer{}
        writer := multipart.NewWriter(body)
        part, err := writer.CreateFormFile(paramName, path)
        if err != nil {
            return nil, err
        }
    # 这里的io.Copy实现,会把file文件都读取到内存里面,然后当做一个buffer传给NewRequest. 对于大文件来说会占用很多内存 _, err = io.Copy(part, file)
    for key, val := range params { _ = writer.WriteField(key, val) } err = writer.Close() if err != nil { return nil, err } request, err := http.NewRequest("POST", uri, body) request.Header.Set("Content-Type", writer.FormDataContentType()) return request, err }

    下面这种方式,就是传入文件句柄,然后由request copy到socket的缓冲区,而不用全部读取到内存中:

        bodyBuf := bytes.NewBufferString("")
        bodyWriter := multipart.NewWriter(bodyBuf)
    
        //建立文件的http第一部分数据,文件信息
        _, err := bodyWriter.CreateFormFile(paramName, path)
        if err != nil {
            return nil, err
        }
    
        //读取文件,当做http第二部分数据
        fh, err := os.Open(path)
        if err != nil {
            return nil, err
        }
        //mulitipart/form-data时,需要获取自己关闭的boundary
        boundary := bodyWriter.Boundary()
        closeBuf := bytes.NewBufferString(fmt.Sprintf("
    --%s--
    ", boundary))
    
        //建立写入socket的reader对象
        requestReader := io.MultiReader(bodyBuf, fh, closeBuf)
    
        fi, err := fh.Stat()
        if err != nil {
            return nil, err
        }
        req, err := http.NewRequest("POST", uri, requestReader)
        if err != nil {
            return nil, err
        }
        //设置http头
        req.Header.Add("Content-Type", "multipart/form-data; boundary="+boundary)
        req.ContentLength = fi.Size() + int64(bodyBuf.Len()) + int64(closeBuf.Len())

    go package 的实现源码:

    http://golang.org/src/io/io.go?s=12247:12307#L340

    https://golang.org/src/io/multi.go?h=MultiReader#L31

    https://golang.org/src/net/http/transfer.go?h=WriteBody#L199

    https://golang.org/src/net/http/request.go?h=write#L366

    参考连接:

    https://groups.google.com/forum/#!topic/golang-nuts/Zjg5l4nKcQ0

  • 相关阅读:
    C++:随机数生成
    C++:typedef 与 #define 的区别
    读书笔记
    从零开始:Spring Security Oauth2 讲解及实战
    SpingCloud:Gateway+Nginx+Stomp+Minio构建聊天室并进行文件传输
    Docker image-Ubuntu(jessie)下postgresql-client安装方法
    7张图了解kafka基本概念
    打包上传python代码到pypi,通过pip安装使用
    Asp.Net Core 中的HTTP协议详解
    LeetCode 1931. Painting a Grid With Three Different Colors(DP)
  • 原文地址:https://www.cnblogs.com/zhangqingping/p/4598337.html
Copyright © 2011-2022 走看看