> 原文连接:[https://www.zhoubotong.site/post/67.html](https://www.zhoubotong.site/post/67.html) Go 标准库的net/url包提供的两个函可以直接检查URL合法性,不需要手动去正则匹配校验。 下面可以直接使用ParseRequestURI()函数解析URL,当然这个只会验证url格式,至于域名是否存在或注册,不会检查的,举个例子:
package main
import (
"fmt"
"net/url"
)
func main() {
url, err := url.ParseRequestURI("https://www.zhoubotong.site") // 注意这里必须带有http/https协议,
//否则会被认定非合法url,但是使用//www.zhoubotong.sit,被返回空,所以error哪里会被绕过,该示例代码不够严谨
if err != nil {
fmt.Println(err)
return
}
fmt.Println(url.Hostname())
}
输出:[www.zhoubotong.site](http://www.zhoubotong.site),下面整个错误的url:
func main() {
url, err := url.ParseRequestURI("www.zhoubotong.site") // www.zhoubotong.site" 或者zhoubotong.site"
if err != nil {
fmt.Println(err)
return
}
fmt.Println(url.Hostname())
}
输出:parse "www.zhoubotong.site": invalid URI for request,既然上面的代码不够严谨,如何改善呢?完整代码如下:
package main
import (
"fmt"
"net/url"
)
func main() {
var u string = "https://www.zhoubotong.site"
_, err := url.ParseRequestURI(u)
if err != nil {
fmt.Println(err)
return
}
url, err := url.Parse(u)
if err != nil || url.Scheme == "" || url.Host == "" {
fmt.Println(err)
return
}
fmt.Println(url.Hostname(), "success")
}
通过上面的两个函数解析url链接,顺便唠叨介绍下这块http/post请求的示例,Get请求示例:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"time"
)
// 定义返回的响应体
type Response struct {
Params string `json:"params"`
Headers map[string]string `json:"headers"`
Origin string `json:"origin"`
Url string `json:"url"`
}
var remoteUrl string = "https://www.baidu.com"
// 获取带参数的http get请求响应数据
func getUrlParse() {
data := url.Values{}
data.Set("username", "乔峰")
data.Set("sex", "male")
u, err := url.ParseRequestURI(remoteUrl)
if err != nil {
fmt.Println(err)
}
u.RawQuery = data.Encode()
fmt.Println(u.RawQuery)
resp, err := http.Get(u.String())
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close() // 一定要关闭释放tcp连接
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
}
// 解析get请求的返回的json结果到struct
func getResultToStruct() {
resp, err := http.Get(remoteUrl)
if err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
var res Response // 定义res为Responser结构体
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
return
}
_ = json.Unmarshal(body, &res) // 注意这里是&res 地址引用
fmt.Printf("%#v\n", res)
}
//get 请求添加头消息
func getHttpByHeader() {
param := url.Values{}
param.Set("username", "babala")
param.Set("sex", "female")
u, _ := url.ParseRequestURI(remoteUrl)
u.RawQuery = param.Encode() // 把参数转换成 sex=female&username=babala
fmt.Println(u)
//重点注意:如果我们直接使用默认的http,那么它是没有超时时间的。这样就会带来性能问题,具体稍后写一篇详细介绍这块
client := &http.Client{Timeout: 10 * time.Second}
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
fmt.Println(err)
}
// 添加请求头header 参数
req.Header.Add("username2", "风清扬")
req.Header