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() 的参数也可以是另一个 URL 实例。这时, URL() 会自动读取该实例的 href 属性,作为实际参数。

如果 URL 字符串是一个相对路径,那么需要表示绝对路径的第二个参数,作为计算基准。

var url1 = new URL('index.html', 'http://example.com');
url1.href
// "http://example.com/index.html"

var url2 = new URL('page2.html', 'http://example.com/page1.html');
url2.href
// "http://example.com/page2.html"

var url3 = new URL('..', 'http://example.com/a/b.html')
url3.href
// "http://example.com/"

上面代码中,返回的 URL 实例的路径都是在第二个参数的基础上,切换到第一个参数得到的。最后一个例子里面,第一个参数是 .. ,表示上层路径。

实例属性

URL 实例的属性与 Location 对象的属性基本一致,返回当前 URL 的信息。

  • URL.href:返回整个 URL
  • URL.protocol:返回协议,以冒号 : 结尾
  • URL.hostname:返回域名
  • URL.host:返回域名与端口,包含 : 号,默认的80和443端口会省略
  • URL.port:返回端口
  • URL.origin:返回协议、域名和端口
  • URL.pathname:返回路径,以斜杠 / 开头
  • URL.search:返回查询字符串,以问号 ? 开头
  • URL.searchParams:返回一个 URLSearchParams 实例,该属性是 Location 对象没有的
  • URL.hash:返回片段识别符,以井号 # 开头
  • URL.password:返回域名前面的密码
  • URL.username:返回域名前面的用户名
var url = new URL('http://user:passwd@www.example.com:4097/path/a.html?x=111#part1');

url.href
// "http://user:passwd@www.example.com:4097/path/a.html?x=111#part1"
url.protocol
// "http:"
url.hostname
// "www.example.com"
url.host
// "www.example.com:4097"
url.port
// "4097"
url.origin
// "http://www.example.com:4097"
url.pathname
// "/path/a.html"
url.search
// "?x=111"
url.searchParams
// URLSearchParams {}
url.hash
// "#part1"
url.password
// "passwd"
url.username
// "user"

这些属性里面,只有 origin 属性是只读的,其他属性都可写,并且会立即生效。

var url = new URL('http://example.com/index.html#part1');

url.pathname = 'index2.html';
url.href // "http://example.com/index2.html#part1"

url.hash = '#part2';
url.href // "http://example.com/index2.html#part2"

上面代码中,改变 URL 实例的 pathname 属性和 hash 属性,都会实时反映在 URL 实例当中。

静态方法

(1)URL.createObjectURL()

URL.createObjectURL() 方法用来为上传/下载的文件、流媒体文件生成一个 URL 字符串。这个字符串代表了 File 对象或 Blob 对象的 URL。

// HTML 代码如下
// <div id="display"/>
// <input
//   type="file"
//   id="fileElem"
//   multiple
//   accept="image/*"
//   onchange="handleFiles(this.files)"
//  >
var div = document.getElementById('display');

function handleFiles(files) {
  for (var i = 0; i < files.length; i++) {
    var img = document.createElement('img');
    img.src = window.URL.createObjectURL(files[i]);
    div.appendChild(img);
  }
}

上面代码中, URL.createObjectURL() 方法用来为上传的文件生成一个 URL 字符串,作为 <img> 元素的图片来源。

该方法生成的 URL 就像下面的样子。

blob:http://localhost/c745ef73-ece9-46da-8f66-ebes574789b1

注意,每次使用 URL.createObjectURL() 方法,都会在内存里面生成一个 URL 实例。如果不再需要该方法生成的 URL 字符串,为了节省内存,可以使用 URL.revokeObjectURL() 方法释放这个实例。

(2)URL.revokeObjectURL()

URL.revokeObjectURL() 方法用来释放 URL.createObjectURL() 方法生成的 URL 实例。它的参数就是 URL.createObjectURL() 方法返回的 URL 字符串。

下面为上一段的示例加上 URL.revokeObjectURL()

var div = document.getElementById('display');

function handleFiles(files) {
  for (var i = 0; i < files.length; i++) {
    var img = document.createElement('img');
    img.src = window.URL.createObjectURL(files[i]);
    div.appendChild(img);
    img.onload = function() {
      window.URL.revokeObjectURL(this.src);
    }
  }
}

上面代码中,一旦图片加载成功以后,为本地文件生成的 URL 字符串就没用了,于是可以在 img.onload 回调函数里面,通过 URL.revokeObjectURL() 方法卸载这个 URL 实例。