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功能:它不是某种编程语言,是一种无需加载整个网页的情况下能够 ...
随机推荐
- Day10 (黑客成长日记) Urllib库的使用
什么是Urllib: Urllib是python内置的HTTP请求库包括以下模块urllib.request 请求模块urllib.error 异常处理模块urllib.parse url解析模块ur ...
- Https,Http,TCP,IP的一些理解
网络模型分为7层,应用层,表现层,会话层,传输层,网络层,链路层,物理层,每一层有很多不同的协议. http:属于应用层的协议,负责的是数据以什么结构传输也可以说成是打包成什么样子 SSL/TLS:属 ...
- UWP关于图片缓存的那些破事儿
看似简单的功能,实施起来却是有着一堆大坑. 按着基本功能来写吧 1.选择图片并显示到Image控件中 2.图片序列化为byte数组以及反序列化 3.本地存储与读取 1.选择图片: 逻辑就是使用File ...
- 玩玩微信公众号Java版之七:自定义微信分享
前面已经学会了微信网页授权,现在微信网页的功能也可以开展起来啦! 首先,我们先来学习一下分享,如何在自己的页面获取分享接口及让小伙伴来分享呢? 今天的主人公: 微信 JS-SDK, 对应官方链接为:微 ...
- html基础知识梳理
1.浏览器内核 补充:blink为Google与Opera共同开发. 2.web标准 web标准为w3c和其他标准化组织制定的一系列标准的集合.(标签闭合.小写.不乱嵌套,使用外链css/js;结构行 ...
- Redhat/CentOS7-环境虚拟机简单搭建Nginx+Tomcat负载均衡集群
Tomcat服务器是一个免费的开放源代码的web应用服务器,属于轻量级应用服务器,是开发和调试JSP程序的首选.由于Tomcat处理静态HTML的能力运不及Apache或者Nginx,所以Tomcat ...
- 玩转Kafka的生产者——分区器与多线程
上篇文章学习kafka的基本安装和基础概念,本文主要是学习kafka的常用API.其中包括生产者和消费者, 多线程生产者,多线程消费者,自定义分区等,当然还包括一些避坑指南. 首发于个人网站:链接地址 ...
- OpenProject 分类专栏说明
OpenProject 顾名思义 开源项目. 一.为何创建 OpenProject 专栏 主要是因为GitHub上收藏的项目越来越多,想在GitHub上查找一些收藏的内容,开始变得比较费时,为了简化搜 ...
- Git使用详细教程(1):工作区、暂存区、本地仓库、远程仓库
之前的写过一篇如何在服务器上搭建Git服务Git服务器搭建,接下来的一段时间,我将详细的讲解Git的使用.看如下一张图片,本篇主要理解一些基本概念. 图中几个名词的意思如下: workspace: 工 ...
- Eclipse 在高分辨率4K显示器下图标按钮过小
买了LG的4K显示器,发现由于分辨率太高,导致好多软件和网站都没进行高分辨率适配,显示比较小,缩放会使好多软件都显示错位.Eclipse就是其中之一. 网上搜了下解决方案如下: 原理 高DPI Win ...