Go Web:URLs
URL也是一个结构体:
type URL struct {
Scheme string
Opaque string // encoded opaque data
User *Userinfo // username and password information
Host string // host or host:port
Path string // path (relative paths may omit leading slash)
RawPath string // encoded path hint (see EscapedPath method)
ForceQuery bool // append a query ('?') even if RawQuery is empty
RawQuery string // encoded query values, without '?'
Fragment string // fragment for references, without '#'
}
URL结构表示解析之后的URL,一般格式为:
[scheme:][//[userinfo@]host][/]path[?query][#fragment]
由于path和query部分只能使用大小写字母、数字以及有限的几个特殊标点,其它所有的字符都需要进行URL编码:百分号+2位16进制数。例如,空格被编码为"%20",斜线被编码为"%2f",有时候query的value中空格会被编码为"+"。
例如,query部分被编码后的内容如下:
name=Hiram%20Veeblefeetzer&age=35&country=Madagascar+abc
它表示3个key/value:name="Hiram Veeblefeetzer"
、age=35
、country=Madagascar abc
。
关于URL,其中:
- Host字段是包含host和port两部分的,如果需要分别返回host、port,使用
URL.Hostname
、URL.Port
- User字段包含了Username和Password,要分别返回它们,使用
URL.User.Username()
,URL.User.Password()
- Path字段表示解码后的URL路径,也就是不带"%"的普通字符串路径
- RawPaht字段表示编码后的安全路径,即带上了"%"的路径
- RawQuery字段表示编码后的Query,即打上了"%"的query字符串,它包含了所有key/value,要分离每个key/value,使用ParseQuery()方法将它们解析到一个map中
URL解析示例
使用URL的Parse(string)
方法可以将字符串构造成一个URL对象,并返回这个URL对象的指针。
现在使用这个方法来构造一个URL对象,并解析其中的各个部分:
package main
import "fmt"
import "net/url"
func main() {
// 将字符串构造成URL对象
s := "postgres://user:pass@host.com:5432/path?k=v#f"
u, err := url.Parse(s)
if err != nil {
panic(err)
}
// 获取schema部分
fmt.Println(u.Scheme)
// User字段包含了Username和Password,需要分别获取
fmt.Println(u.User)
fmt.Println(u.User.Username())
p, _ := u.User.Password()
fmt.Println(p)
// Host字段包含了hostname和port
fmt.Println(u.Host)
fmt.Println(u.Hostname())
fmt.Println(u.Port())
// 取得Path和Fragment字段
fmt.Println(u.Path)
fmt.Println(u.Fragment)
// 取得query的key/value
// 要取出各个key/value,使用ParseQuery()将RawQuery字段解析成map
// key是字符串,value是字符串的slice,如果有key相同,则多个值放进这个slice
fmt.Println(u.RawQuery)
m, _ := url.ParseQuery(u.RawQuery)
fmt.Println(m)
fmt.Println(m["k"][0])
}
结果:
postgres
user:pass
user
pass
host.com:5432
host.com
5432
/path
f
k=v
map[k:[v]]
v
构造URL
URL的Parse(string)
方法可以将字符串构造成一个URL对象,URL的String()方法可以返回编码后的URL值。
例如:
urlstr := "http://www.cnblogs.com/f-ck-need-u"
myurl,_ := url.Parse(urlstr)
fmt.Println(myurl.String())
输出:
http://www.cnblogs.com/f-ck-need-u
由于URL的path和query部分可能包含特殊字符,直接使用纯字符串构造URL会不安全。应该使用另外两个函数将普通字符转换成编码后的字符:
func PathEscape(s string) string
func QueryEscape(s string) string
再将编码之后的path和query作为Parse()方法的一部分。
例如:
package main
import (
"fmt"
"net/url"
)
func main() {
// 要构造:http://www.example.int/下
// Path: search
// Query: food=pie aaa
// action=like
// 的URL
s := "http://www.example.int"
p := "search"
path := url.PathEscape(p)
// query部分
qfood := "pie aaa"
qaction := "like"
qqfood := url.QueryEscape(qfood)
qqaction := url.QueryEscape(qaction)
// 将query组合起来
query := "food=" + qqfood + "&action=" + qqaction
// 构造url
myurlstr := s + "/" + path + "?" + query
myurl, err := url.Parse(myurlstr)
if err != nil {
panic(err)
}
// 解析URL
fmt.Println(myurl.String())
// 解析url的query部分
fmt.Println(myurl.RawQuery)
qmaps, _ := url.ParseQuery(myurl.RawQuery)
fmt.Println(qmaps["food"])
fmt.Println(qmaps["action"])
}
这很麻烦,对于Query部分,更好的方法是使用Values.Encode()方法,见后文。
url Path部分
在URL结构中:有Path和RawPath两个字段
type URL struct{
...
Path string // path (relative paths may omit leading slash)
RawPath string // encoded path hint (see EscapedPath method)
...
}
其中Path是解码后的路径,RawPath是编码后的路径。
前面解释了PathEscape()函数,它是将字符串转换为编码后的字符串,可以直接将编码后的结果作为构造url的path部分,这样是最安全的构造方式。
除此之外,还有一个EscapePath()方法:如果RawPath存在且有效,则直接返回RawPath字段的值,如果不存在,则EscapePath()自己计算一个编码后的路径。
URL.String()方法是直接调用EscapePath()来构造路径部分的。
Userinfo
type Userinfo
func User(username string) *Userinfo
func UserPassword(username, password string) *Userinfo
func (u *Userinfo) Password() (string, bool)
func (u *Userinfo) String() string
func (u *Userinfo) Username() string
User()函数构造一个Userinfo,但只包含Username不包含password。
UserPassword()函数构造一个Userinfo,包含Username和password,但因为明文显示,不建议使用。
String()返回"username[:password]"格式的username和Password。
Username()和Password()分别返回对应的部分。
Query部分
URL结构中有一个RawQuery字段:
type URL struct {
...
RawQuery string
...
}
RawQuery字段是编码后的query。
有几个方法:
func (u *URL) Query() Values
它读取RawQuery字段的值并返回Values类型。但会直接丢弃错误或畸形的query部分,如果要检查错误或畸形,使用ParseQuery()函数。
注意上面Query()的返回值是Values类型,它是一个map结构:
type Values map[string][]string
func ParseQuery(query string) (Values, error)
func (v Values) Add(key, value string)
func (v Values) Del(key string)
func (v Values) Encode() string
func (v Values) Get(key string) string
func (v Values) Set(key, value string)
ParseQuery()函数解析给定字符串query并将query的各个部分填充到返回值类型Values的map结构中,同时会检查错误。
Add()、Del()、Set()和Get()都用来操作Values的map结构,意义都很清晰。唯一需要注意的是,Add()是追加操作,Set()是替换已有值,如果操作的key不存在,则直接创建。
Encode()是将Values中的数据根据key排序后编码成URL的query,且是编码后的query。
下面是一个用法:
package main
import (
"fmt"
"net/url"
)
func main() {
s := "http://www.example.int"
p := "search"
path := url.PathEscape(p)
// query部分
values := url.Values{}
values.Set("food","pie aaa")
values.Add("action","like")
values.Add("name","abc")
values.Add("name","def")
values.Add("name","gh")
// Encode() == "action=like&food=pie+aaa&name=abc&name=def&name=gh"
query := values.Encode()
// 构造url
myurlstr := s + "/" + path + "?" + query
myurl, err := url.Parse(myurlstr)
if err != nil {
panic(err)
}
// 解析url
fmt.Println(myurl.String())
}
Go Web:URLs的更多相关文章
- Go Web:处理请求
处理请求 Request和Response http Requset和Response的内容包括以下几项: Request or response line Zero or more headers ...
- 未来的 Web:九个不可思议的 WebGL 应用试验
WebGL 技术允许把 JavaScript 和 OpenGL ES 2.0 结合在一起,通过增加 OpenGL ES 2.0 的一个 JavaScript 绑定,WebGL 可以为 HTML5 Ca ...
- web:转盘抽奖
移动web:转盘抽奖(幸运大转盘) 为了获取客户.回馈客户,平台一般会推出抽奖活动类的营销页.因此web页面中,有各式各样的抽奖效果. 格子式(九宫格),背景滚动式(数字/文字/图案),旋转式(转 ...
- 《Mining the Web:Transforming Customer Data into Customer Value》读后札记
<Mining the Web:Transforming Customer Data into Customer Value> <Web数据挖掘:将客户数据转化为客户价值> — ...
- 信息安全-技术-Web:cookie
ylbtech-信息安全-技术-Web:cookie Cookie,有时也用其复数形式 Cookies,指某些网站为了辨别用户身份.进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密 ...
- 【Pro ASP.NET MVC 3 Framework】.学习笔记.12.ASP.NET MVC3的细节:URLs,Routing和Areas
Adam Applied ASP.NET 4 in Context 1 介绍Routing系统 在引入MVC之前,ASP.NET假定被请求的URLs和服务器硬盘上的文件之间有着直接关系.服务器的任务是 ...
- 初识WEB:输入URL之后的故事
1. 概述2. HTTP请求过程3. 相关性能检测及优化手段4. 浏览器的呈现过程5. 浏览器的呈现引擎6. 引用及延伸阅读 概述 为什么输入www.cnblogs.com之后敲一个回车,浏览器就会显 ...
- 初识WEB:输入URL之后的故事【转】
转载一篇文章,分析的是浏览器输入url后所执行的一系列操作!写得非常清晰易懂,分享给大家! 作者:Jesse 出处:http://jesse2013.cnblogs.com/ 本文版权归作者和博客园共 ...
- Web:AJAX的详解
Web中的AJAX技术: 1.介绍:全称:Asnchronous JavaScript and XML,即异步的JavaScript和XML功能:它不是某种编程语言,是一种无需加载整个网页的情况下能够 ...
随机推荐
- idea取消double shift全局搜索
一是因为它和输入法经常冲突,二来是因为它完全可以被其它的快捷键代替,如Ctrl+n,ctrl+shift+n,ctrl+shift+f之类的: 取消的方法,按ctrl+shift+a,然后输入regi ...
- 基于继承的 MethodInterceptor 动态代理(换种写法)
net.sf.cglib.proxy.Enhancer Generates dynamic subclasses to enable method interception. This class s ...
- 简述Oracle IOT(Index Organized Table)
转:http://blog.itpub.net/17203031/viewspace-744477 对关系型数据库产品(RDBMS)而言,一个重要特性就是:数据信息都被组织为二维数据表,信息的表达可以 ...
- im4java+GraphicsMagick 的问题
1.convert.exe: non-conforming drawing primitive definition `' @ error/draw.c/RenderMVGContent/3901. ...
- ppt演讲者模式
步骤如下: 1 win+p 2 选择扩展 3 选幻灯片放映 4 设置幻灯片放映 5 显示器二 6 勾选显示演示者视图
- 团队-Forward团队-团队一阶段互评
团队名称:Forward团队 学号:2015035107105 得分:7 原因:知识欠缺,能够一边学一边做 学号:2015035107109 得分:6 原因:对我有很多帮助 学号:2015035107 ...
- Servlet中的jsp内置对象
Servlet和jsp本质相同,那么为什么还要使用jsp呢,原来的servlet又有什么不好的呢. Servlet和jsp可以做完全相同的事情,就要借助jsp的内置对象们,比如request,resp ...
- Windows下安装BeautifulSoup4显示'You are trying to run the Python 2 version of Beautiful Soup under Python 3.(`python setup.py install`) or by running 2to3 (`2to3 -w bs4`).'
按照网上教程,将cmd的目录定位到解压缩文件夹地址,然后 >>python setup.py install ( Window下不能直接解压tar.giz文件,可以使用7z解压软件提取解压 ...
- 【Node100In1】01.去异步,解决掉Node.js万恶的回调陷阱
Node.js是基于事件驱动编程.异步函数随处可见,其中不乏一些常用库的方法.本例就以js中最常见的setTimeout的为例,试图改善一下回调的书写. 先来看一段伪代码: 我们实现一个需求,每隔一段 ...
- 吴恩达机器学习笔记35-诊断偏差和方差(Diagnosing Bias vs. Variance)
当你运行一个学习算法时,如果这个算法的表现不理想,那么多半是出现两种情况:要么是偏差比较大,要么是方差比较大.换句话说,出现的情况要么是欠拟合,要么是过拟合问题.那么这两种情况,哪个和偏差有关,哪个和 ...