GO_HTTP
GO原生支持http, import("net/http")
package main
import (
"fmt"
"net/http"
)
func Hello(w http.ResponseWriter, r *http.Request){
fmt.Println("handle hello")
fmt.Fprintf(w, "hello") // 向响应写入内容
}
func main(){
http.HandleFunc("/", Hello) // 路由对应关系
err := http.ListenAndServe("127.0.0.1:8000", nil) // 监听IP端口
if err != nil{
fmt.Println("http listen failed")
}
}
访问一个网络地址
get请求
package main
import (
"fmt"
"net/http"
"io/ioutil"
"os"
"bufio"
)
func main(){
// 文件
file, err := os.OpenFile("aa.jpg", os.O_WRONLY|os.O_CREATE, 0666)
if err != nil{
fmt.Println("file err", err)
}
defer file.Close()
bufferWriter := bufio.NewWriter(file)
// 请求
imf_url :=`http://pic.58pic.com/58pic/13/74/51/99d58PIC6vm_1024.jpg`
res, err := http.Get(imf_url) // 请求地址
if err != nil{
fmt.Println("get err:", err)
return
}
data, err := ioutil.ReadAll(res.Body) //
if err != nil{
fmt.Println("data err:",err)
return
}
_, err = bufferWriter.Write(data)
bufferWriter.Flush()
}
head请求
package main
import (
"fmt"
"net/http"
"time"
"net"
// "io/ioutil"
// "os"
// "bufio"
)
// func main(){
// var url = []string{
// "https://www.baidu.com/",
// "http://google.com",
// "http://taobao.com",
// }
// for _, v := range url{
// rep, err := http.Head(v)
// if err != nil{
// fmt.Printf("head %s failesd, err: %v\n", v, err)
// continue
// }
// fmt.Printf("head succ status%v\n", rep.Status)
// }
// }
//设置超时时间
func main(){
var url = []string{
"https://www.baidu.com/",
"http://google.com",
"http://taobao.com",
}
c := http.Client{
Transport: &http.Transport{
Dial:func(network, addrs string)(net.Conn, error){
timeout := time.Second*2
return net.DialTimeout(network, addrs, timeout)
},
},
}
for _, v := range url{
rep, err := c.Head(v)
if err != nil{
fmt.Printf("head %s failesd, err: %v\n", v, err)
continue
}
fmt.Printf("head succ status%v\n", rep.Status)
}
}
源码浅析
// http下
func Head(url string) (resp *Response, err error) {
return DefaultClient.Head(url)
}
// 使用了一个默认的连接去执行指定的方法
var DefaultClient = &Client{}
// 在Client结构体中, Transport定义了连接使用的机制, 他是一个接口定义了RoundTrip(*Request) (*Response, error)方法
// http.Transport是实现了该接口的, 其中的Dial是创建连接的一个函数network, addr分别是连接类型和地址
// net.DialTimeout返回一个有超时时间的连接
请求头和请求类型
package main
import (
"io"
"net/http"
)
const form = `<html><body><form action="#" method="post" name="bar">
<input type="text" name="in"/>
<input type="text" name="in"/>
<input type="submit" value="Submit"/>
</form></html></body>`
func FormServer(w http.ResponseWriter, request *http.Request) {
w.Header().Set("Content-Type", "text/html")
switch request.Method {
case "GET":
io.WriteString(w, form)
case "POST":
request.ParseForm() // 先要解析这个表单
io.WriteString(w, request.Form["in"][0]) // 方式一取到input的值是个列表
io.WriteString(w, "\n")
io.WriteString(w, request.FormValue("in"))// 取到一个, 这两个的区别就像Django中request的value和value_list
}
}
func main() {
http.HandleFunc("/test2", FormServer)
if err := http.ListenAndServe(":8088", nil); err != nil {
}
}
使用装饰器来处理异常
func main() {
http.HandleFunc("/test1", logPanics(SimpleServer))
http.HandleFunc("/test2", logPanics(FormServer))
if err := http.ListenAndServe(":8088", nil); err != nil {
}
}
func logPanics(handle http.HandlerFunc) http.HandlerFunc { // 将原来的处理函数封装, 增加异常处理
return func(writer http.ResponseWriter, request *http.Request) {
defer func() {
if x := recover(); x != nil {
log.Printf("[%v] caught panic: %v", request.RemoteAddr, x)
}
}()
handle(writer, request)
}
}
模板
package main
import (
"fmt"
"os"
"text/template" // 导入template包
)
type Person struct {
Name string
age string
}
func main() {
t, err := template.ParseFiles("./index.html") // 引入模板文件
if err != nil {
fmt.Println("parse file err:", err)
return
}
p := Person{Name: "Mary", age: "31"}
if err := t.Execute(os.Stdout, p); err != nil { // 将数据对象与模板结合并输出
fmt.Println("There was an error:", err.Error())
}
}
模板语法
{{.}} // 表示传进去的变量
{{.attr}} // 取属性
{{ if gt .Age 18}} gt 大于
// 逻辑操作符
// not
// and
// or
// 更多比较操作符
// eq 等于
// ne 不等于
// lt 小于
// le 小于等于
// gt 大于
// ge 大于等于
{{else}}
{{end}}
// 循环一个可循环的结构
{{range .}}
{{end}}

浙公网安备 33010602011771号