Go 語(yǔ)言 獲取URL

2023-03-14 16:48 更新

原文鏈接:https://gopl-zh.github.io/ch1/ch1-05.html


1.5. 獲取URL

對(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)碼。



以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)