I'd like to parse the response of a web request, but I'm getting trouble accessing it as string.

func main() {
    resp, err := http.Get("http://google.hu/")
    if err != nil {
        // handle error
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)

    ioutil.WriteFile("dump", body, 0600)

    for i:= 0; i < len(body); i++ {
        fmt.Println( body[i] ) // This logs uint8 and prints numbers
    }

    fmt.Println( reflect.TypeOf(body) )
    fmt.Println("done")
}

How can I access the response as string? ioutil.WriteFile writes correctly the response to a file.

I've already checked the package reference but it's not really helpful.

Tibor Szasz

Ответов: 4

Ответы (4)

bs := string(body) should be enough to give you a string.

From there, you can use it as a regular string.

A bit as in this thread
(updated after Go 1.16 -- Q1 2021 -- ioutil deprecation: ioutil.ReadAll() => io.ReadAll()):

var client http.Client
resp, err := client.Get(url)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

if resp.StatusCode == http.StatusOK {
    bodyBytes, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }
    bodyString := string(bodyBytes)
    log.Info(bodyString)
}

See also GoByExample.

As commented below (and in zzn's answer), this is a conversion (see spec).
See "How expensive is []byte(string)?" (reverse problem, but the same conclusion apply) where zzzz mentioned:

Some conversions are the same as a cast, like uint(myIntvar), which just reinterprets the bits in place.

Sonia adds:

Making a string out of a byte slice, definitely involves allocating the string on the heap. The immutability property forces this.
Sometimes you can optimize by doing as much work as possible with []byte and then creating a string at the end. The bytes.Buffer type is often useful.

Go 1.16+ update (February 2021)

Deprecation of io/ioutil

code should be

var client http.Client
resp, err := client.Get(url)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

if resp.StatusCode == http.StatusOK {
    bodyBytes, err := io.ReadAll(resp.Body)
    // if u want to read the body many time
    // u need to restore 
    // reader := io.NopCloser(bytes.NewReader(bodyBytes))
    if err != nil {
        log.Fatal(err)
    }
    bodyString := string(bodyBytes)
    log.Info(bodyString)
}

reference

  1. https://golang.org/doc/go1.16#ioutil
  2. https://stackoverflow.com/a/52076748/2876087

string(byteslice) will convert byte slice to string, just know that it's not only simply type conversion, but also memory copy.

The method you're using to read the http body response returns a byte slice:

func ReadAll(r io.Reader) ([]byte, error)

official documentation

You can convert []byte to a string by using

body, err := ioutil.ReadAll(resp.Body)
bodyString := string(body)

2022 WebDevInsider