Skip to content

Location 和 URL

URI(Uniform Resource Identifier,统一资源标识符)

  • 定义:用于标识某一资源的字符串,是一种更广义的资源定位方式。
  • 作用:告诉你“这个资源是什么”,即资源的身份标识。
  • 分类
    • URL(Uniform Resource Locator,统一资源定位符):URI 的一个子集,表示资源的地址,可以直接访问。
    • URN(Uniform Resource Name,统一资源名称):URI 的另一子集,表示资源的名字,不一定能直接定位到资源。

URL 是互联网的基础设施之一。浏览器提供了一些原生对象,用来管理 URL。

Location 对象

Location对象是浏览器提供的原生对象,提供 URL 相关的信息和操作方法。通过window.locationdocument.location属性,可以拿到这个对象。

属性

Location对象提供以下属性。

js
// 当前网址:
// 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 地址,浏览器会立刻跳转到这个新地址,这个特性常常用于让网页自动滚动到新的内容锚点。

js
// 两者功能类似,都会跳转锚点而不刷新页面
document.location.href = '#top';
document.location.hash = '#top';

要实现自动滚动到某个元素,也可以用现代方法scrollIntoView

js
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-zA-Z0-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 A5E8 8A 82,将每个字节前面加上百分号,就构成了 URL 编码。

JavaScript 提供四个 URL 的编码/解码方法。

  • encodeURI()
  • encodeURIComponent()
  • decodeURI()
  • decodeURIComponent()

encodeURI() decodeURI()

encodeURI()方法用于转码整个 URL。 它会将元字符和语义字符之外的字符,都进行转义。

decodeURI()方法用于整个 URL 的解码。它是encodeURI()`方法的逆运算。

js
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() 是它的逆运算

js
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,会报错。

js
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()方法释放这个实例。

html
<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 问号后面的部分)。

它本身也是一个构造函数,可以生成实例。参数可以为查询字符串,起首的问号?有没有都行,也可以是对应查询字符串的数组或对象。

js
// 方法一:传入字符串
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实例。

js
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 的例子。

js
// 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()

形如对象的遍历。