什么是 URI
?
URI
和 URL
的区别是?
URI
的编码方法?
如果不知道的话就往下看看吧~
什么是 URI
URI
(Uniform Resource Identifier),也就是 统一资源标识符 。
它的 作用 就是区分互联网上不同的资源。
URI
包括两个部分:
URL
(Uniform Resource Location),统一资源定位符 。URN
(Uniform Resource Name),统一资源名称 。
URI
的 结构:
scheme
:// user:passwd
@ host:port
path
? query
#fragment
scheme 表示协议名,比如 http
, https
, file
等等。后面必须和 ://
连在一起。协议可以自定义。
user:passwd@ 表示登陆主机时的用户名和密码,不过很不安全,不推荐使用,也不常用。
host:port 表示主机名和端口。
path 表示请求路径,标记资源所在位置。
query 表示查询参数 ,以?
开始,为 key = val
键值对的形式 ,以 &
隔开。
fragment 也叫哈希。表示 URI
所定位的资源内的一个锚点,浏览器可以根据这个锚点跳转到对应位置。
例子:
https://www.baidu.com/s?wd=HTTP&rsv_spt=1#heading-8
https
即 scheme
协议
www.baidu.com
即 host:port
主机名和端口。注意,http
和 https
的默认端口分别是80、443。
/s
即 path
请求路径,标记资源所在位置。
wd=HTTP&rsv_spt=1
即 query
参数部分,且为两个。
heading-8
即 fragment
锚点。
URL
为 https://www.baidu.com/s?wd=HTTP&rsv_spt=1
URN
为 www.baidu.com/s?wd=HTTP&rsv_spt=1#heading-8
URI
编码方法
URI 只能使用ASCII
, ASCII 之外的字符是不支持显示的,而且还有一部分符号是界定符,如果不加以处理就会导致解析出错。
因此,URI 引入了 编码机制 ,将所有非 ASCII 码字符和界定符转为十六进制字节值,然后在前面加个%
。
如,空格被转义成了%20
,布纳纳被转义成了 %E5%B8%83%E7%BA%B3%E7%BA%B3
。
encodeURI()
和 encodeURIComponent()
encodeURI()
和 encodeURIComponent()
方法用于编码统一资源标识符(URI),以便传给浏览器。
encodeURI()
方法用于对整个 URI 进行编码encodeURIComponent()
方法用于编码 URI 中单独的组件,
let uri = "https://zhuanlan.zhihu.com/p/40311981?redirect=a"
console.log(encodeURI(uri))
// https://zhuanlan.zhihu.com/p/40311981?redirect=a
// 使用 encodeURI()编码后,除空格被替换为%20 之外,没有任何变化。
console.log(encodeURIComponent(uri))
// https%3A%2F%2Fzhuanlan.zhihu.com%2Fp%2F40311981%3Fredirect%3Da
// encodeURIComponent()方法将所有非字母字符都替换成了相应的编码形式。
因此,我们发现这两个方法的 主要区别 是:encodeURI()
不会编码属于 URL 组件的特殊字符,比如冒号、斜杠、问号、 井号,而 encodeURIComponent()
会编码它发现的所有非标准字符。这就是使用 encodeURI()
编码整个 URI,但只使用 encodeURIComponent()
编码那些会追加到已有 URI 后面的字符串的原因。
注意 一般来说,使用 encodeURIComponent()
比使用 encodeURI()
的频率更高, 这是因为编码查询字符串参数比编码基准 URI 的次数更多。
decodeURI()
和 decodeURIComponent()
-
decodeURI()
只对使用encodeURI()
编码过的 字符解码。 -
同样,
decodeURIComponent()
只对使用encodeURIComponent()
编码过的字符解码 ,基本上就是解码所有特殊值。
例子:
let uri = "http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.js%23start";
console.log(decodeURI(uri));
// http%3A%2F%2Fwww.wrox.com%2Fillegal value.js%23start
console.log(decodeURIComponent(uri));
// http:// www.wrox.com/illegal value.js#start
这里,uri 变量中包含一个使用 encodeURIComponent()
编码过的字符串。
首先输出的是使用 decodeURI()
解码的结果,可以看到只用空格替换了%20
。
然后是使用 decodeURIComponent()
解码的 结果,其中替换了所有特殊字符,并输出了没有包含任何转义的字符串。(这个字符串不是有效的 URL。)
如何获取 URI
参数?
// 1.取 ? 开头,# 结尾 的字符串
// 2.根据 & 分割参数
// 3.根据 = 分割键值对
function getParams(str){
// ? 的索引
const startIdx = str.indexOf('?') + 1;
const endIdx = str.indexOf('#')
const paramString = str.substring(startIdx ,endIdx);
console.log('paramString:' + paramString)
const kvArr = paramString.split('&');
console.log('kvArr:' + kvArr)
const params = {};
kvArr.forEach(item =>{
const [k,v] = item.split('=');
params[k] = v;
});
return params;
}
console.log(getParams('https://zhuanlan.zhihu.com/p/40311981?redirect=a¶m=b#heading-8'));
https://zhuanlan.zhihu.com/p/40311981?redirect=https://www.baidu.com?a=10¶m=b#heading-8
的参数是?
console.log(getParams('https://zhuanlan.zhihu.com/p/40311981?redirect=https://www.baidu.com?a=10¶m=b#heading-8'));
// {redirect: "https://www.baidu.com?a", param: "b"}
这明显不对, redirect
的值应该是 https://www.baidu.com?a=10
。解决:
let redirect = "https://www.baidu.com?a"
let uri = `https://zhuanlan.zhihu.com/p/40311981?redirect=${encodeURIComponent(redirect)}¶m=b#heading-8`
console.log(getParams(uri))
如果想让参数只有 redirect
且值是 https://www.baidu.com?a=10¶m=b
呢?
let redirect1 = "https://www.baidu.com?a=10¶m=b"
let uri1 = `https://zhuanlan.zhihu.com/p/40311981?redirect=${encodeURIComponent(redirect1)}#heading-8`
console.log(getParams(uri1))
最后
如有问题请大佬指正~
如有帮助,希望能够点赞收藏~
参考资料:
- JavaScript高级程序设计(第4版)
- 维基百科的统一资源标志符
- (建议精读)HTTP灵魂之问,巩固你的 HTTP 知识体系
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!