http.Client 使用範例

// Fetch makes network calls using the method (POST/GET..), the URL // to hit, headers to add (if any), and the body of the request.
// Feel free to add more stuff to before/after making the actual n/w call!
func Fetch(method string, url string, header map[string]string, body io.Reader) (*http.Response, err) {
  // Create client with required custom parameters.
  // Options: Disable keep-alives, 30sec n/w call timeout.
  client := &http.Client{
      Transport: &http.Transport{
          DisableKeepAlives: true,
      },
      Timeout: time.Duration(10 * time.Second),
  }
  // Create request.
  req, _ := http.NewRequest(method, url, body)
  // Add any required headers.
  for key, value := range header {
      req.Header.Add(key, value)
  } 
  // Perform said network call.
  res, err := client.Do(req)
      if err != nil {
      glog.Error(err.Error())   // use glog it's amazing
      return nil, err
  }
  // If response from network call is not 200, return error too.
  if res.StatusCode != http.StatusOK {
      return res, errors.New("Network call did not return SUCCESS!")
  }
  return res, nil
}

傳送資料範例

package main

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

func httpGet() {
    resp, err := http.Get("http://www.01happy.com/demo/accept.php?id=1")
    if err != nil {
        // handle error
    }

    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        // handle error
    }

    fmt.Println(string(body))
}

func httpPost() {
    resp, err := http.Post("http://www.01happy.com/demo/accept.php",
        "application/x-www-form-urlencoded",
        strings.NewReader("name=cjb"))
    if err != nil {
        fmt.Println(err)
    }

    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        // handle error
    }

    fmt.Println(string(body))
}

func httpPostForm() {
    resp, err := http.PostForm("http://www.01happy.com/demo/accept.php",
        url.Values{"key": {"Value"}, "id": {"123"}})

    if err != nil {
        // handle error
    }

    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        // handle error
    }

    fmt.Println(string(body))

}

func httpDo() {
    client := &http.Client{}

    req, err := http.NewRequest("POST", "http://www.01happy.com/demo/accept.php", strings.NewReader("name=cjb"))
    if err != nil {
        // handle error
    }

    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    req.Header.Set("Cookie", "name=anny")

    resp, err := client.Do(req)

    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        // handle error
    }

    fmt.Println(string(body))
}

func main() {
    httpGet()
    httpPost()
    httpPostForm()
    httpDo()
}

GET複雜的用法

    client := &http.Client{}
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        log.Fatalln(err)
    }
    req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36")

    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }

    defer resp.Body.Close()

透過GET轉成JSON

    client := &http.Client{}
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        log.Fatalln(err)
    }
    req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36")

    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }

    defer resp.Body.Close()

  • 範例二
func makeGetRequestToStatusApi(urlToGet string) (string, error) {
  req, err := http.NewRequest(http.MethodGet, urlToGet, nil)
  if err != nil {
    return "", err
  }

  ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
  defer cancel()
  req = req.WithContext(ctx)

  req.Header.Set("Accept", "application/json")

  res, err := http.DefaultClient.Do(req)
  if err != nil {
    urlErr := err.(*url.Error)
    message := "there was %s when attempting to request the URL %s: %s"
    return "", fmt.Errorf(message, getTypeOfError(urlErr), urlErr.URL, err)
  }
  defer res.Body.Close()

  if res.StatusCode/100 == 4 || res.StatusCode/100 == 5 {
    return "", fmt.Errorf("the response was returned with a %d", res.StatusCode)
  }

  var resBody string
  if err = json.NewDecoder(res.Body).Decode(&resBody); err != nil {
    return "", err
  }

  return resBody, nil
}

func main() {
  urls := []string{"http://httpstat.us/200", "http://httpstat.us/404", "http://httpstat.us/201?sleep=2000", "http://httpstat.us/201"}

  for _, url := range urls {
    if resBody, err := makeGetRequestToStatusApi(url); err != nil {
      fmt.Printf("there was an error when getting %s: %v\n", url, err)
    } else {
      fmt.Printf("the response from %s: %s\n", url, resBody)
    }
  }
}