W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
原文鏈接:https://gopl-zh.github.io/ch1/ch1-05.html
對(duì)于很多現(xiàn)代應(yīng)用來(lái)說(shuō),訪問(wèn)互聯(lián)網(wǎng)上的信息和訪問(wèn)本地文件系統(tǒng)一樣重要。Go語(yǔ)言在net這個(gè)強(qiáng)大package的幫助下提供了一系列的package來(lái)做這件事情,使用這些包可以更簡(jiǎn)單地用網(wǎng)絡(luò)收發(fā)信息,還可以建立更底層的網(wǎng)絡(luò)連接,編寫(xiě)服務(wù)器程序。在這些情景下,Go語(yǔ)言原生的并發(fā)特性(在第八章中會(huì)介紹)顯得尤其好用。
為了最簡(jiǎn)單地展示基于HTTP獲取信息的方式,下面給出一個(gè)示例程序fetch,這個(gè)程序?qū)@取對(duì)應(yīng)的url,并將其源文本打印出來(lái);這個(gè)例子的靈感來(lái)源于curl工具(譯注:unix下的一個(gè)用來(lái)發(fā)http請(qǐng)求的工具,具體可以man curl)。當(dāng)然,curl提供的功能更為復(fù)雜豐富,這里只編寫(xiě)最簡(jiǎn)單的樣例。這個(gè)樣例之后還會(huì)多次被用到。
gopl.io/ch1/fetch
// Fetch prints the content found at a URL.
package main
import (
"fmt"
"io/ioutil"
"net/http"
"os"
)
func main() {
for _, url := range os.Args[1:] {
resp, err := http.Get(url)
if err != nil {
fmt.Fprintf(os.Stderr, "fetch: %v\n", err)
os.Exit(1)
}
b, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
fmt.Fprintf(os.Stderr, "fetch: reading %s: %v\n", url, err)
os.Exit(1)
}
fmt.Printf("%s", b)
}
}
這個(gè)程序從兩個(gè)package中導(dǎo)入了函數(shù),net/http和io/ioutil包,http.Get函數(shù)是創(chuàng)建HTTP請(qǐng)求的函數(shù),如果獲取過(guò)程沒(méi)有出錯(cuò),那么會(huì)在resp這個(gè)結(jié)構(gòu)體中得到訪問(wèn)的請(qǐng)求結(jié)果。resp的Body字段包括一個(gè)可讀的服務(wù)器響應(yīng)流。ioutil.ReadAll函數(shù)從response中讀取到全部?jī)?nèi)容;將其結(jié)果保存在變量b中。resp.Body.Close關(guān)閉resp的Body流,防止資源泄露,Printf函數(shù)會(huì)將結(jié)果b寫(xiě)出到標(biāo)準(zhǔn)輸出流中。
$ go build gopl.io/ch1/fetch
$ ./fetch http://gopl.io
<html>
<head>
<title>The Go Programming Language</title>title>
...
HTTP請(qǐng)求如果失敗了的話,會(huì)得到下面這樣的結(jié)果:
$ ./fetch http://bad.gopl.io
fetch: Get http://bad.gopl.io: dial tcp: lookup bad.gopl.io: no such host
譯注:在大天朝的網(wǎng)絡(luò)環(huán)境下很容易重現(xiàn)這種錯(cuò)誤,下面是Windows下運(yùn)行得到的錯(cuò)誤信息:
$ go run main.go http://gopl.io
fetch: Get http://gopl.io: dial tcp: lookup gopl.io: getaddrinfow: No such host is known.
無(wú)論哪種失敗原因,我們的程序都用了os.Exit函數(shù)來(lái)終止進(jìn)程,并且返回一個(gè)status錯(cuò)誤碼,其值為1。
練習(xí) 1.7: 函數(shù)調(diào)用io.Copy(dst, src)會(huì)從src中讀取內(nèi)容,并將讀到的結(jié)果寫(xiě)入到dst中,使用這個(gè)函數(shù)替代掉例子中的ioutil.ReadAll來(lái)拷貝響應(yīng)結(jié)構(gòu)體到os.Stdout,避免申請(qǐng)一個(gè)緩沖區(qū)(例子中的b)來(lái)存儲(chǔ)。記得處理io.Copy返回結(jié)果中的錯(cuò)誤。
練習(xí) 1.8: 修改fetch這個(gè)范例,如果輸入的url參數(shù)沒(méi)有 http://
前綴的話,為這個(gè)url加上該前綴。你可能會(huì)用到strings.HasPrefix這個(gè)函數(shù)。
練習(xí) 1.9: 修改fetch打印出HTTP協(xié)議的狀態(tài)碼,可以從resp.Status變量得到該狀態(tài)碼。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: