Location 和 URL
URI(Uniform Resource Identifier,统一资源标识符)
- 定义:用于标识某一资源的字符串,是一种更广义的资源定位方式。
- 作用:告诉你“这个资源是什么”,即资源的身份标识。
- 分类:
- URL(Uniform Resource Locator,统一资源定位符):URI 的一个子集,表示资源的地址,可以直接访问。
- URN(Uniform Resource Name,统一资源名称):URI 的另一子集,表示资源的名字,不一定能直接定位到资源。
URL 是互联网的基础设施之一。浏览器提供了一些原生对象,用来管理 URL。
Location 对象
Location对象是浏览器提供的原生对象,提供 URL 相关的信息和操作方法。通过window.location和document.location属性,可以拿到这个对象。
属性
Location对象提供以下属性。
// 当前网址:
// http://www.example.com:4097/path/a.html?x=111#part1
document.location.href
// "http://www.example.com:4097/path/a.html?x=111#part1"
document.location.protocol
// "http:"`
document.location.host
// "www.example.com:4097"
document.location.hostname
// "www.example.com"`
document.location.port
// "4097"`
document.location.pathname
// "/path/a.html"`
document.location.search
// "?x=111"`
document.location.hash
// "#part1"`
document.location.origin
// "http://www.example.com:4097"如果对Location写入新的 URL 地址,浏览器会立刻跳转到这个新地址,这个特性常常用于让网页自动滚动到新的内容锚点。
// 两者功能类似,都会跳转锚点而不刷新页面
document.location.href = '#top';
document.location.hash = '#top';要实现自动滚动到某个元素,也可以用现代方法scrollIntoView
document.getElementById('top')
.scrollIntoView({ behavior: 'smooth' });方法
(1)Location.assign()
会触发跳转
(2)Location.replace()
会触发跳转
它与assign方法的差异在于,replace会在浏览器的浏览历史History里面直接替换URL,一旦使用了该方法,后退按钮就无法回到上一网页。 应用场景:当脚本发现当前是移动设备时,就立刻跳转到移动版网页。
(3)Location.reload()
reload方法使得浏览器重新加载当前网址,相当于按下浏览器的刷新按钮。
它接受一个布尔值作为参数。如果参数为true,浏览器将向服务器重新请求这个网页,并且重新加载后滚动到头部(即scrollTop === 0)。如果参数是false或为空,浏览器将从本地缓存重新加载该网页,并且重新加载后,网页的视口位置是重新加载前的位置。
(4)Location.toString()
toString方法返回整个 URL 字符串,相当于读取Location.href属性。
URL 的编码和解码
网页的 URL 只能包含合法的字符,合法字符包括两类:
- URL 保留字符:分号(
;),逗号(,),斜杠(/),问号(?),冒号(:),at(@),&,等号(=),加号(+),美元符号($),井号(#) - 通常的语义字符:
a-z,A-Z,0-9,连词号(-),下划线(_),点(.),感叹号(!),波浪线(~),星号(*),单引号('),圆括号(())
除了以上字符,其他字符出现在 URL 之中都必须转义,此外,如果语义中想要包含元字符,也需要对元字符进行转义。 规则是根据操作系统的默认编码,将每个字节转为%加上两个大写十六进制字母。
比如,UTF-8 的操作系统上,http://www.example.com/q=春节这个 URL 之中,汉字“春节”不是 URL 的合法字符,所以被浏览器自动转成http://www.example.com/q=%E6%98%A5%E8%8A%82。其中,“春”转成了%E6%98%A5,“节”转成了%E8%8A%82。这是因为“春”和“节”的 UTF-8 编码分别是E6 98 A5和E8 8A 82,将每个字节前面加上百分号,就构成了 URL 编码。
JavaScript 提供四个 URL 的编码/解码方法。
encodeURI()encodeURIComponent()decodeURI()decodeURIComponent()
encodeURI() decodeURI()
encodeURI()方法用于转码整个 URL。 它会将元字符和语义字符之外的字符,都进行转义。
decodeURI()方法用于整个 URL 的解码。它是encodeURI()`方法的逆运算。
encodeURI('http://www.example.com/q=春节')
// "http://www.example.com/q=%E6%98%A5%E8%8A%82"
decodeURI("http://www.example.com/q=%E6%98%A5%E8%8A%82")
// "http://www.example.com/q=春节"encodeURIComponent()
encodeURIComponent()方法用于转码 URL 的部分
会转码除了语义字符之外的所有字符,即元字符也会被转码。
decodeURIComponent() 是它的逆运算
encodeURIComponent('春节')
// "%E6%98%A5%E8%8A%82"
encodeURIComponent('b1/b2')
// "b1%2Fb2"
encodeURIComponent('http://www.example.com/q=春节')
// "http%3A%2F%2Fwww.example.com%2Fq%3D%E6%98%A5%E8%8A%82"
// 这是不合理的
decodeURIComponent("%E6%98%A5%E8%8A%82")
// "春节"URL 接口
URL接口是一个构造函数,浏览器原生提供,可以用来构造、解析和编码 URL。一般情况下,通过window.URL可以拿到这个构造函数。
构造函数
URL作为构造函数,可以生成 URL 实例。它接受一个表示 URL 的字符串作为参数。如果参数不是合法的 URL,会报错。
var url = new URL('http://www.example.com/index.html');
url.href
// "http://www.example.com/index.html上面代码中,返回的 URL 实例的路径都是在第二个参数的基础上,切换到第一个参数得到的。最后一个例子里面,第一个参数是..,表示上层路径。
实例属性
URL 实例的属性与Location对象的属性基本一致,返回当前 URL 的信息。
静态方法
(1)URL.createObjectURL() URL.createObjectURL()
URL.createObjectURL()方法用来为上传/下载的文件、流媒体文件生成一个 URL 字符串。这个字符串代表了File对象或Blob对象的 URL。
每次使用URL.createObjectURL()方法,都会在内存里面生成一个 URL 实例。如果不再需要该方法生成的 URL 字符串,为了节省内存,可以使用URL.revokeObjectURL()方法释放这个实例。
<div id="display" />
<input type="file" id="fileElem" multiple accept="image/*" onchange="handleFiles(this)">
<script>
var div = document.getElementById('display');
function handleFiles(e) {
const files = e.files
for (var i = 0; i < files.length; i++) {
var img = document.createElement('img');
const url = window.URL.createObjectURL(files[i]);
img.src = url
div.appendChild(img);
img.onload = function(){
console.log('revokeObjectURL !')
window.URL.revokeObjectURL(url);
}
}
}
</script>
上面代码中,URL.createObjectURL()方法用来为上传的文件生成一个 URL 字符串,作为<img>元素的图片来源。
该方法生成的 URL 形如: blob:http://localhost/c745ef73-ece9-46da-8f66-ebes574789b1
在使用 revokeObjectURL 之后,再想通过这个链接访问图片,就访问不到了。
URLSearchParams 对象
概述
URLSearchParams对象是浏览器的原生对象,用来构造、解析和处理 URL 的查询字符串(即 URL 问号后面的部分)。
它本身也是一个构造函数,可以生成实例。参数可以为查询字符串,起首的问号?有没有都行,也可以是对应查询字符串的数组或对象。
// 方法一:传入字符串
var params = new URLSearchParams('?foo=1&bar=2');
// 等同于
var params = new URLSearchParams(document.location.search);
// 方法二:传入数组
var params = new URLSearchParams([['foo', 1], ['bar', 2]]);
// 方法三:传入对象
var params = new URLSearchParams({'foo' : 1 , 'bar' : 2});URLSearchParams会对查询字符串自动编码,向服务器发送表单数据时,可以直接使用URLSearchParams实例作为表单数据。
fetch命令向服务器发送命令时,可以直接使用URLSearchParams实例。
const params = new URLSearchParams({foo: 1, bar: 2});
fetch('https://example.com/api', {
method: 'POST',
body: params
}).then(...).toString()
toString方法返回实例的字符串形式。
.append()
append()方法用来追加一个查询参数。它接受两个参数,第一个为键名,第二个为键值,没有返回值。
var params = new URLSearchParams({'foo': 1 , 'bar': 2});params.append('baz', 3);params.toString() // "foo=1&bar=2&baz=3"
.delete()
delete()方法用来删除指定的查询参数。它接受键名作为参数。
.has()
has()方法返回一个布尔值,表示查询字符串是否包含指定的键名。
.set()
set()方法用来设置查询字符串的键值。
它接受两个参数,第一个是键名,第二个是键值。如果是已经存在的键,键值会被改写,否则会被追加。
下面是一个替换当前 URL 的例子。
// URL: https://example.com?version=1.0
var params = new URLSearchParams(location.search.slice(1));
params.set('version', 2.
window.history.replaceState({}, '', location.pathname + `?` + params);
// URL: https://example.com?version=2.0.get(),.getAll()
get()方法用来读取查询字符串里面的指定键。它接受键名作为参数。 getAll()方法返回一个数组,成员是指定键的所有键值。它接受键名作为参数。
.sort()
sort()方法对查询字符串里面的键进行排序,规则是按照 Unicode 码点从小到大排列。
.keys(),.values(),.entries()
形如对象的遍历。