坐云独酌杯盘湿,穿竹微吟路径斜。javascript
URI(Uniform Resource Identifier,统一资源标识符):一个资源的惟一标识。HTTP 请求的内容通称为"资源"。”资源“这一律念很是宽泛,它能够是一份文档,一张图片,或全部其余你可以想到的格式。每一个资源都由一个 (URI) 来进行标识。java
URL(Uniform Resource Locator,统一资源定位器):也被称做web地址,它是一种具体的URI,即URL能够用来标识一个资源,并且还指明了如何定位这个资源(网络位置)。通俗地说,URL是Internet上用来描述资源的字符串,主要用在各类www客户端和服务器程序。web
URN(Universal Resource Name, 统一资源名称):URN是基于某命名空间经过名称指定资源的URI。人们能够经过URN来指出某个资源,而无需指出其位置和得到方式。资源无需是基于互联网的。浏览器
URI能够分为URL,URN或同时具有locators 和names特性的一个东西。URN做用就好像一我的的名字,URL就像一我的的地址。换句话说:URN肯定了东西的名称,URL提供了找到它的方式,而URI表明资源的惟一标识。安全
URL和URN都是URI的子集。服务器
"只有字母和数字[0-9a-zA-Z]、一些特殊符号"$-_.+!*'(),"[不包括双引号]、以及某些保留字,才能够不通过编码直接用于URL。"网络
若是URL中有汉字,就必须编码后使用,可是麻烦的是,RFC1738没有规定具体的编码方法, 而是交给应用程序(浏览器)本身决定,这致使'URL编码'成为了一个混乱的领域.。函数
接下来咱们介绍一下URL编解码的几种方式。ui
该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它,但也许会在将来的某个时间中止支持,请尽可能不要使用该特性。this
古老的escape()不能直接用于URL编码,它的真正做用是返回一个字符的Unicode编码值。 它的具体规则是,除了ASCII字母、数字、标点符号"@ * _ + - . /"之外,对其余全部字符进行编码。在u0000到u00ff之间的符号被转成%xx的形式,其他符号被转成%uxxxx的形式。对应的解码函数是unescape()。
escape("王总");
escape("abc123");
escape("@*_+-./");
escape("http://www.bingshangroup.com?name=王总&slogen=属实");
// %u738B%u603B
// abc123
// @*_+-./
// http%3A//www.bingshangroup.com%3Fname%3D%u738B%u603B%26slogen%3D%u5C5E%u5B9E
复制代码
它着眼于对整个URL进行编码,所以除了常见的符号之外,对其余一些在网址中有特殊含义的符号也不进行编码。编码后,它输出符号的utf-8形式,而且在每一个字节前加上%。
它对应的解码函数是decodeURI()。
encodeURI 会替换全部的字符,但不包括如下字符,即便它们具备适当的UTF-8转义序列:
类型 | 包含 |
---|---|
保留字符 | ; , / ? : @ & = + $ |
非转义的字符 | 字母 数字 - _ . ! ~ * ' ( ) |
数字符号 | # |
encodeURI('http://www.bingshangroup.com?name=王总&slogen=属实');
encodeURI('http://www.bingshangroup.com?group=wangzong&mayi=web');
// http://www.bingshangroup.com?name=%E7%8E%8B%E6%80%BB&slogen=%E5%B1%9E%E5%AE%9E
// http://www.bingshangroup.com?group=wangzong&mayi=web
复制代码
&
=
不会被编码,然而在 GET 和 POST 请求中它们是特殊字符,致使了请求参数获取的错误
与encodeURI()的区别是,它用于对URL的组成部分进行个别编码,而不用于对整个URL进行编码。 它对应的解码函数是decodeURIComponent()。
encodeURIComponent 转义除了字母 数字 (
)
.
!
~
*
'
-
和_
以外的全部字符。
encodeURIComponent('http://www.bingshangroup.com?name=王总&slogen=属实');
encodeURIComponent('http://www.bingshangroup.com?group=wangzong&mayi=web');
// http%3A%2F%2Fwww.bingshangroup.com%3Fname%3D%E7%8E%8B%E6%80%BB%26slogen%3D%E5%B1%9E%E5%AE%9E
// http%3A%2F%2Fwww.bingshangroup.com%3Fgroup%3Dwangzong%26mayi%3Dweb
复制代码
为了更严格的遵循 RFC 3986(保留 !
'
(
)
和 *
),即便这些字符并无正式划定 URI 的用途,下面这种方式是比较安全的:
function fixedEncodeURIComponent (str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16);
});
}
复制代码
[
和 ]
保留给了IPV6
function fixedEncodeURI (str) {
return encodeURI(str).replace(/%5B/g, '[').replace(/%5D/g, ']');
}
复制代码
如何把对象转换成查询字符串
var objectToQueryString = (obj) => Object.keys(obj).map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`).join('&');
objectToQueryString({name:王总, slogen:属实})
复制代码
又或者你能够这样玩(想一下原理是什么)
class FormData {
constructor(key, value) {
this.key = key;
this.value = value;
}
toString() {
return encodeURIComponent(this.key) + '=' + encodeURIComponent(this.value);
}
}
let items = [
new FormData('王总', '属实'),
new FormData('mayi', 'yahei')
];
console.log(items.join('&'));
复制代码