GO的URL合法性檢查

来源:https://www.cnblogs.com/phpper/archive/2022/08/11/16576423.html
-Advertisement-
Play Games

原文連接:https://www.zhoubotong.site/post/67.html Go 標準庫的net/url包提供的兩個函可以直接檢查URL合法性,不需要手動去正則匹配校驗。 下麵可以直接使用ParseRequestURI()函數解析URL,當然這個只會驗證url格式,至於功能變數名稱是否存在或 ...


原文連接: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.Add("age1", "89")
    resp, _ := client.Do(req)
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(body))

}

func main() {
    getResultToStruct()
    getHttpByHeader()
}
發送post請求示例:
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
    "strings"
    "time"
)

var remoteUrl = "https://www.zhoubotong.site"

// 發送表單post請求
func postByForm() {
    param := url.Values{}
    param.Add("username", "喬峰")
    param.Add("sex", "male")
    resp, _ := http.PostForm(remoteUrl, param) // 表單提交"Content-Type": "application/x-www-form-urlencoded"
    defer resp.Body.Close()
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

// 發送表單提交,可以對比上面的postByForm的實現差異
func postByForm2() {
    urlValue := url.Values{
    "username": {"喬峰"},
    "sex":      {"male"},
}
    respData := urlValue.Encode()
    fmt.Println(respData) // encode轉碼:name=%E4%B9%94%E5%B3%B0&sex=male
    resp, _ := http.Post(remoteUrl, "text/html", strings.NewReader(respData))
    //註意接收數據類型為text/html,對應在postman中的x-www-form-urlencoded中的key value參數
    defer resp.Body.Close()
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

// 發送json數據
func postJson() {
    client := &http.Client{Timeout: time.Second * 10}
    param := make(map[string]interface{})
    param["username"] = "喬峰"
    param["sex"] = "male"
    respdata, _ := json.Marshal(param) // respdata[]byte類型,轉化成string類型便於查看
    req, _ := http.NewRequest("POST", remoteUrl, bytes.NewReader(respdata))
    //http.NewRequest請求會自動發送header中的Content-Type為applcation/json,對應在postman中的body的raw的json參數
    resp, _ := client.Do(req)
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

// 發送json數據,註意和上面實現的區別
func postJson2() {
    param := make(map[string]interface{})
    param["username"] = "喬峰"
    param["sex"] = "male"
    respdata, _ := json.Marshal(param) // respdata[]byte類型,轉化成string類型便於查看
    fmt.Println(string(respdata))
    resp, _ := http.Post(remoteUrl, "application/json", bytes.NewReader(respdata))
    defer resp.Body.Close()
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

/*
對應的postman中params中的key value參數,我估計很多人都很迷惑postman工具的params和body兩個地方傳遞參數的區別,
其實Params處設置的變數請求時會url後問號傳參(?x=y)。而Body里設置的參數則是介面真正請求時發的參數,下麵這個例子就是通過params傳參
*/
func postString() {
    param := url.Values{}
    param.Add("username", "babala")
    param.Add("sex", "female")
    u, _ := url.ParseRequestURI(remoteUrl)
    u.RawQuery = param.Encode()
    fmt.Println(u)
    client := &http.Client{}
    req, _ := http.NewRequest("POST", u.String(), nil) // 註意發送數據類似為string的post請求,對應的postman中params中的key value參數
    resp, _ := client.Do(req)
    defer resp.Body.Close()
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

func main() {
    //postByForm()
    //postByForm2()
    //postJson()
    //postJson2()
    postString()

}
通過上面的示例介紹,涉及了日常開發中各種場景的請求類型,基本滿足了常規開發,以上只是示例,後端如何處理數據,大家可以自行解析參數返回試試。
無論從事什麼行業,只要做好兩件事就夠了,一個是你的專業、一個是你的人品,專業決定了你的存在,人品決定了你的人脈,剩下的就是堅持,用善良專業和真誠贏取更多的信任。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ##網路協議 通過電腦網路可以使多台電腦實現連接,位於同一個網路中的電腦在進行連接和通信時需要遵守一定的規則,這就好比在道路中行駛的汽車一定要遵守交通規則一樣。在電腦網路中,這些連接和通信的規則被稱為網路通信協議,它對數據的傳輸格式、傳輸速率、傳輸步驟等做了統一規定,通信雙方必須同時遵守才能 ...
  • 《笨辦法學Python3 》免費下載地址 內容簡介 · · · · · · 本書是一本Python入門書籍,適合對電腦瞭解不多,沒有學過編程,但對編程感興趣的讀者學習使用。這本書以習題的方式引導讀者一步一步學習編程,從簡單的列印一直講到完整項目的實現,讓初學者從基礎的編程技術入手,最終體驗到軟體開 ...
  • 啥是函數式介面、它和JAVA中普通的介面有啥區別?函數式介面有啥用?如何在實際編碼中使用函數式介面?帶著這些問題,我們一起來認識下函數式介面的廬山真面目。 ...
  • 函數是基於功能或者邏輯進行聚合的可復用的代碼塊。將一些複雜的、冗長的代碼抽離封裝成多個代碼片段,即函數,有助於提高代碼邏輯的可讀性和可維護性。不同於Python,由於 Go lang是編譯型語言,編譯之後再運行,所以函數的定義順序無關痛癢。 函數聲明 在 Go lang里,函數聲明語法如下: fun ...
  • 《Python高手之路 第3版》|免費下載地址 作者簡介 · · · · · · Julien Danjou 具有12年從業經驗的自由軟體黑客。擁有多個開源社區的不同身份:Debian開發者、Freedesktop貢獻者、GNU Emacs提交者、awesome視窗管理器的創建者以及OpenStac ...
  • 《紅樓夢》作為我國四大名著之一,古典小說的巔峰之作,粉絲量極其龐大,而紅學也經久不衰。所以我們今天通過 Python 來探索下紅樓夢裡那千絲萬縷的人物關係,話不多說,開始整活! 一、準備工作 紅樓夢txt格式電子書一份 金陵十二釵+賈寶玉人物名稱列表 寶玉 nr 黛玉 nr 寶釵 nr 湘雲 nr ...
  • “什麼是IO的多路復用機制?” 這是一道年薪50W的面試題,很遺憾,99%的人都回答不出來。 大家好,我是Mic,一個工作了14年的Java程式員。 今天,給大家分享一道網路IO的面試題。 這道題目的文字回答已經整理到了15W字的面試文檔裡面,大家可以S我領取。 下麵看看高手的回答。 高手: IO多 ...
  • 多商戶商城系統,也稱為B2B2C(BBC)平臺電商模式多商家商城系統。可以快速幫助企業搭建類似拼多多/京東/天貓/淘寶的綜合商城。 多商戶商城系統支持商家入駐加盟,同時滿足平臺自營、旗艦店等多種經營方式。平臺可以通過收取商家入駐費,訂單交易服務費,提現手續費,簡訊通道費等多手段方式,實現整體盈利。 ...
一周排行
    -Advertisement-
    Play Games
  • 一:背景 1.講故事 在分析的眾多dump中,經常會遇到各種奇葩的問題,僅通過dump這種快照形式還是有很多問題搞不定,而通過 perfview 這種粒度又太粗,很難找到問題之所在,真的很頭疼,比如本篇的 短命線程 問題,參考圖如下: 我們在 t2 時刻抓取的dump對查看 短命線程 毫無幫助,我根 ...
  • 在日常後端Api開發中,我們跟前端的溝通中,通常需要協商好入參的數據類型,和參數是通過什麼方式存在於請求中的,是表單(form)、請求體(body)、地址欄參數(query)、還是說通過請求頭(header)。 當協商好後,我們的介面又需要怎麼去接收這些數據呢?很多小伙伴可能上手就是直接寫一個實體, ...
  • 許多情況下我們需要用到攝像頭獲取圖像,進而處理圖像,這篇博文介紹利用pyqt5、OpenCV實現用電腦上連接的攝像頭拍照並保存照片。為了使用和後續開發方便,這裡利用pyqt5設計了個相機界面,後面將介紹如何實現,要點包括界面設計、邏輯實現及完整代碼。 ...
  • 思路分析 註冊頁面需要對用戶提交的數據進行校驗,並且需要對用戶輸入錯誤的地方進行提示! 所有我們需要使用forms組件搭建註冊頁面! 平時我們書寫form是組件的時候是在views.py裡面書寫的, 但是為了接耦合,我們需要將forms組件都單獨寫在一個地方,需要用的時候導入就行! 例如,在項目文件 ...
  • 思路分析 登錄頁面,我們還是採用ajax的方式提交用戶數據 唯一需要學習的是如何製作圖片驗證碼! 具體的登錄頁面效果圖如下: 如何製作圖片驗證碼 推導步驟1:在img標簽的src屬性里放上驗證碼的請求路徑 補充1.img的src屬性: 1.圖片路徑 2.url 3.圖片的二進位數據 補充2:字體樣式 ...
  • 哈嘍,兄弟們! 最近有許多小伙伴都在吐槽打工好難。 每天都是執行許多重覆的任務 例如閱讀新聞、發郵件、查看天氣、打開書簽、清理文件夾等等, 使用自動化腳本,就無需手動一次又一次地完成這些任務, 非常方便啊有木有?! 而在某種程度上,Python 就是自動化的代名詞。 今天就來和大家一起學習一下, 用 ...
  • 作者:IT王小二 博客:https://itwxe.com 前面小二介紹過使用Typora+PicGo+LskyPro打造舒適寫作環境,那時候需要使用水印功能,但是小二在升級LskyPro2.x版本發現有很多不如人意的東西,遂棄用LskyPro使用MinIO結合代碼實現自己需要的圖床功能,也適合以後 ...
  • OpenAI Gym是一款用於研發和比較強化學習演算法的工具包,本文主要介紹Gym模擬環境的功能和工具包的使用方法,並詳細介紹其中的經典控制問題中的倒立擺(CartPole-v0/1)問題。最後針對倒立擺問題如何建立控制模型並採用爬山演算法優化進行了介紹,並給出了相應的完整python代碼示例和解釋。要... ...
  • python爬蟲瀏覽器偽裝 #導入urllib.request模塊 import urllib.request #設置請求頭 headers=("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, l ...
  • 前端代碼搭建 主要利用的是bootstrap3中js插件里的模態框版塊 <li><a href="" data-toggle="modal" data-target=".bs-example-modal-lg">修改密碼</a></li> <div class="modal fade bs-exam ...