escape 转义string 到url query
转化 %AB 为 byte 0xAB 以及 ‘+’ 到 ’ ’ (space)
type Error struct {
Op string
URL string
Err error
}
Error reports an error and the operation and URL that caused it.
func (e *Error) Error() string { return e.Op + " " + e.URL + ": " + e.Err.Error() }
t, ok := e.Err.(timeout)
return ok && t.Timeout()
}
type URL struct {
Scheme string
Opaque string // encoded opaque(加密) data
User *Userinfo // username and password information
Host string // host or host:port
Path string
RawPath string // encoded path hint (Go 1.5 and later only; see EscapedPath method)
RawQuery string // encoded query values, without '?'
Fragment string // fragment for references, without '#'
}
URL一般形式:
scheme://[userinfo@]host/path[?query][#fragment]
不带斜线的URLs,解释为:
scheme:opaque[?query][#fragment]
注意:Path是以解码的形式出现: /%47%6f%2f becomes /Go/.这样就造成了不可能区分那一斜线是对应的斜线,那一个是%2f,这些并不重要,但是一旦使用了,就的使用原来的形式。
例子:
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
u, err := url.Parse("http://bing.com/search?q=dotnet")
if err != nil {
log.Fatal(err)
}
u.Scheme = "https"
u.Host = "google.com"
q := u.Query()
q.Set("q", "golang")
u.RawQuery = q.Encode()
fmt.Println(u)
}
结果: https://google.com/search?q=golang
例子(Opaque的例子)
package main
import (
"fmt"
"log"
"net/http"
"net/http/httputil"
"net/url"
"strings"
)
func main() {
// Sending a literal '%' in an HTTP request's Path
req := &http.Request{
Method: "GET",
Host: "example.com", // takes precedence over URL.Host
URL: &url.URL{
Host: "ignored",
Scheme: "https",
Opaque: "/%2f/",
},
Header: http.Header{
"User-Agent": {"godoc-example/0.1"},
},
}
out, err := httputil.DumpRequestOut(req, true)
if err != nil {
log.Fatal(err)
}
fmt.Println(strings.Replace(string(out), "\r", "", -1))
}
结果:
GET /%2f/ HTTP/1.1
Host: example.com
User-Agent: godoc-example/0.1
Accept-Encoding: gzip
Roundtrip 例子
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
// Parse + String preserve the original encoding.
u, err := url.Parse("https://example.com/foo%2fbar")
if err != nil {
log.Fatal(err)
}
fmt.Println(u.Path)
fmt.Println(u.RawPath)
fmt.Println(u.String())
}
解析一个加密了的url到url
类似上面
返回转义形式的path
反回一个URL是否是一个绝对路径
parse 在接受者的基础上解析一个url
Query 解析 加密了的RawQuery 反悔相关的value
返回加密的PATH
本方法根据一个绝对URI将一个URI补全为一个绝对URI,参见RFC 3986 节 5.2。参数ref可以是绝对URI或者相对URI。ResolveReference总是返回一个新的URL实例,即使该实例和u或者ref完全一样。如果ref是绝对URI,本方法会忽略参照URI并返回ref的一个拷贝。
例子:
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
u, err := url.Parse("../../..//search?q=dotnet")
if err != nil {
log.Fatal(err)
}
base, err := url.Parse("http://example.com/directory/")
if err != nil {
log.Fatal(err)
}
fmt.Println(base.ResolveReference(u))
}
Userinfo类型是一个URL的用户名和密码细节的一个不可修改的封装。一个真实存在的Userinfo值必须保证有用户名(但根据 RFC 2396可以是空字符串)以及一个可选的密码。
User函数返回一个用户名设置为username的不设置密码的*Userinfo。
UserPassword函数返回一个用户名设置为username、密码设置为password的*Userinfo。
这个函数应该只用于老式的站点,因为风险很大,不建议使.用
Values将建映射到值的列表。它一般用于查询的参数和表单的属性。不同于http.Header这个字典类型,Values的键是大小写敏感的。
例子:
package main
import (
"fmt"
"net/url"
)
func main() {
v := url.Values{}
v.Set("name", "Ava")
v.Add("friend", "Jess")
v.Add("friend", "Sarah")
v.Add("friend", "Zoe")
// v.Encode() == "name=Ava&friend=Jess&friend=Sarah&friend=Zoe"
fmt.Println(v.Get("name"))
fmt.Println(v.Get("friend"))
fmt.Println(v["friend"])
}
out:
Ava
Jess
[Jess Sarah Zoe]
ParseQuery函数解析一个URL编码的查询字符串,并返回可以表示该查询的Values类型的字典。本函数总是返回一个包含了所有合法查询参数的非nil字典,err用来描述解码时遇到的(如果有)第一个错误。
1. func (v Values) Get(key string) string
1. Get会获取key对应的值集的第一个值。如果没有对应key的值集会返回空字符串。获取值集请直接用map。
1. func (v Values) Set(key, value string)
1. func (v Values) Add(key, value string)
1. func (v Values) Del(key string)
Encode方法将v编码为url编码格式(“bar=baz&foo=quux”),编码时会以键进行排序。