夜猫子的知识栈 夜猫子的知识栈
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

夜猫子

前端练习生
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • canvas
  • clipboard
  • fetch
  • fontface
  • formdata
  • geolocation
  • headers
  • intersectionObserver
  • intl-relativetimeformat
  • intl-segmenter
  • offline
  • page-lifecycle
  • page-visibility
  • pointer-lock
  • postmessage
  • request
  • response
  • server-sent-events
  • service-worker
  • svg
  • url
  • urlpattern
    • 简介
    • 构造函数 URLPattern()
      • 基本用法
      • 模式写法
    • 实例属性
    • 实例方法
      • exec()
      • test()
  • urlsearchparams
  • web-share-api
  • webaudio
  • webcomponents
  • websocket
  • 《Web Api》笔记
夜猫子
2024-09-06
目录

urlpattern

# URL Pattern API

# 简介

URL Pattern API 基于正则表达式和通配符,对 URL 进行匹配和解析。

它提供一个构造函数URLPattern(),用于新建一个 URL 模式实例。

const pattern = new URLPattern(input);
1

有了模式实例,就可以知道某个 URL 是否符合该模式。

const pattern = new URLPattern({ pathname: "/books" });
console.log(pattern.test("https://example.com/books")); // true
1
2

上面示例中,模式实例是 包含/books路径的 URL,实例方法test()用来检测指定网址是否符合该模式,结果为true。

URL Pattern 支持多种协议,不仅是 HTTP 协议。

const pattern = new URLPattern("data\\:foo*");
1

上面示例中,URL Pattern 新建了一个 Data 协议的模式。

# 构造函数 URLPattern()

# 基本用法

构造函数URLPattern()用于新建一个 URL 模式实例。

const pattern = new URLPattern(input);
1

该构造函数的参数input是一个模式字符串或者模式对象。

new URLPattern("https://example.com/books/:id")
// {
//   hasRegExpGroups: false,
//   hash: "*",
//   hostname: "example.com",
//   password: "*",
//   pathname: "/books/:id",
//   port: "",
//   protocol: "https",
//   search: "*",
//   username: "*",
//   ...
// }
1
2
3
4
5
6
7
8
9
10
11
12
13

上面示例中,参数https://example.com/books/:id就是一个模式字符串,执行后返回一个 URLPattern 实例对象,包含模式的各个组成部分。

参数input也可以写成一个对象,用属性指定模式 URL 的每个部分。也就是说,模式对象可以有以下属性。

  • protocol
  • username
  • password
  • hostname
  • port
  • pathname
  • search
  • hash
  • baseURL

上面的示例,如果参数改成模式对象,就是下面这样。

new URLPattern({
  protocol: 'https',
  hostname: 'example.com',
  pathname: '/books/:id',
})
1
2
3
4
5

模式字符串或者模式对象之中,没有定义的部分,默认为*,表示所有可能的字符,包括零字符的情况。

URLPattern()正常情况下将返回一个 URLPattern 实例对象,但是遇到参数无效或语法不正确,则会报错。

new URLPattern(123) // 报错
1

上面示例中,参数123不是一个有效的 URL 模式,就报错了。

需要注意的是,如果模式字符串为相对路径,那么URLPattern()还需要第二个参数,用来指定基准 URL。

new URLPattern(input, baseURL)
1

上面代码中,第二个参数baseURL就是基准 URL。

new URLPattern('/books/:id') // 报错
new URLPattern('/books/:id', 'https://example.com') // 正确
1
2

上面示例中,第一个参数/books/:id是一个相对路径,这时就需要第二个参数https://example.com,用来指定基准 URL,否则报错。

但是,如果参数为模式对象,则可以只指定 URL 模式的某个部分。

new URLPattern({
  pathname: '/books/:id'
}) // 正确
1
2
3

上面示例中,参数是一个模式对象,那么参数允许只指定 URL 的部分模式。

模式对象里面,也可以指定基准 URL。

let pattern4 = new URLPattern({
  pathname: "/books/:id",
  baseURL: "https://example.com",
});
1
2
3
4

基准 URL 必须是合法的 URL,不能包含模式。

注意,如果用了模式对象,就不能使用基准 URL 作为第二个参数,这样会报错。

new URLPattern({ pathname: "/foo/bar" }, "https://example.com") // 报错
new URLPattern({ pathname: "/foo/bar" }, "https://example.com/baz") // 报错
1
2

上面示例中,同时使用了模式对象和第二个参数,结果就报错了。

URLpattern()还可以加入配置对象参数,用于定制匹配行为。

new URLPattern(input, options)
new URLPattern(input, baseURL, options)
1
2

上面代码中,参数options就是一个配置对象。

目前,这个配置对象options只有ignoreCase一个属性,如果设为true,将不区分大小写,默认值为false,表示区分大小写。

new URLPattern(input, {
  ignoreCase: false // 默认值,区分大小写
})
1
2
3

请看下面的例子。

const pattern = new URLPattern("https://example.com/2022/feb/*");

pattern.test("https://example.com/2022/feb/xc44rsz") // true
pattern.test("https://example.com/2022/Feb/xc44rsz") // false
1
2
3
4

上面示例,默认匹配时,会区分feb和Feb。

我们可以用ignoreCase将其关闭。

const pattern = new URLPattern(
  "https://example.com/2022/feb/*",
  {  ignoreCase: true, }
);

pattern.test("https://example.com/2022/feb/xc44rsz") // true
pattern.test("https://example.com/2022/Feb/xc44rsz") // true
1
2
3
4
5
6
7

# 模式写法

模式字符串基本上采用正则表达式的写法,但是不是所有的正则语法都支持,比如先行断言和后行断言就不支持。

(1)普通字符

如果都是普通字符,就表示原样匹配。

const p = new URLPattern('https://example.com/abc');
1

上面代码就表示确切匹配路径https://example.com/abc。

p.test('https://example.com') // false
p.test('https://example.com/a') //false
p.test('https://example.com/abc') // true
p.test('https://example.com/abcd') //false
p.test('https://example.com/abc/') //false
p.test('https://example.com/abc?123') //true
1
2
3
4
5
6

上面示例中,URL 必须严格匹配路径https://example.com/abc,即使尾部多一个斜杠都不行,但是加上查询字符串是可以的。

(2)?

量词字符?表示前面的字符串,可以出现0次或1次,即该部分可选。

let pattern = new URLPattern({
  protocol: "http{s}?",
});
1
2
3

上面示例中,{s}?表示字符组s可以出现0次或1次。

?不包括路径的分隔符/。

const pattern = new URLPattern("/books/:id?", "https://example.com");

pattern.test("https://example.com/books/123") // true
pattern.test("https://example.com/books") // true
pattern.test("https://example.com/books/") // false
pattern.test("https://example.com/books/123/456") // false
pattern.test("https://example.com/books/123/456/789") // false
pattern.test("https://example.com/books/123/456/") // false
1
2
3
4
5
6
7
8

上面示例中,?不能匹配网址结尾的斜杠。

如果一定要匹配,可以把结尾的斜杠放在{}里面。

const pattern = new URLPattern({ pathname: "/product{/}?" });

pattern.test({ pathname: "/product" }) // true
pattern.test({ pathname: "/product/" }) // true
1
2
3
4

上面示例中,不管网址有没有结尾的斜杠,{/}?都会成功匹配。

(3)+

量词字符+表示前面的字符串出现1次或多次。

const pattern = new URLPattern({
  pathname: "/books/(\\d+)",
})
1
2
3

上面示例中,\\d+表示1个或多个数字,其中的\d是一个内置的字符类,表示0-9的数字,因为放在双引号里面,所以反斜杠前面还要再加一个反斜杠进行转义。

+可以包括/分隔的路径的多个部分,但不包括路径结尾的斜杠。

const pattern = new URLPattern("/books/:id+", "https://example.com");

pattern.test("https://example.com/books/123") // true
pattern.test("https://example.com/books") // false
pattern.test("https://example.com/books/") // false
pattern.test("https://example.com/books/123/456") // true
pattern.test("https://example.com/books/123/456/789") // true
pattern.test("https://example.com/books/123/456/") // false
1
2
3
4
5
6
7
8

(4)*

量词字符*表示出现零次或多次。

const pattern = new URLPattern('https://example.com/{abc}*');

pattern.test('https://example.com') // true
pattern.test('https://example.com/') // true
pattern.test('https://example.com/abc') // true
pattern.test('https://example.com/abc/') // false
pattern.test('https://example.com/ab') // false
pattern.test('https://example.com/abcabc') // true
pattern.test('https://example.com/abc/abc/abc') // false
1
2
3
4
5
6
7
8
9

上面示例中,{abc}*表示abc出现零次或多次,也不包括路径分隔符/。

如果*前面没有任何字符,就表示所有字符,包括零字符的情况,也包括分隔符/。

let pattern = new URLPattern({
  search: "*",
  hash: "*",
});
1
2
3
4

上面示例中,*表示匹配所有字符,包括零字符。

下面是另一个例子。

const pattern = new URLPattern("/*.png", "https://example.com");

pattern.test("https://example.com/image.png") // true
pattern.test("https://example.com/image.png/123") // false
pattern.test("https://example.com/folder/image.png") // true
pattern.test("https://example.com/.png") // true
1
2
3
4
5
6

*匹配的部分可以从对应部分的数字属性上获取。

const pattern = new URLPattern({
  hostname: "example.com",
  pathname: "/foo/*"
});

const result = pattern.exec("/foo/bar", "https://example.com/baz");

result.pathname.input // '/foo/bar'
result.pathname.groups[0] // 'bar'
1
2
3
4
5
6
7
8
9

上面示例中,*的匹配结果可以从pathname.groups[0]获取。

const pattern = new URLPattern({ hostname: "*.example.com" });
const result = pattern.exec({ hostname: "cdn.example.com" });

result.hostname.groups[0] // 'cdn'
result.hostname.input // 'cdn.example.com'
1
2
3
4
5

上面示例中,*的匹配结果可以从hostname.groups[0]获取。

(5){}

特殊字符{}用来定义量词?、+、+的生效范围。

如果{}后面没有量词,那就跟没有使用的效果一样。

const pattern = new URLPattern('https://example.com/{abc}');

pattern.test('https://example.com/') // false
pattern.test('https://example.com/abc') // true
1
2
3
4

(6)()

特殊字符()用来定义一个组匹配,匹配结果可以按照出现顺序的编号,从pathname.groups对象上获取。

const pattern = new URLPattern("/books/(\\d+)", "https://example.com");
pattern.exec("https://example.com/books/123").pathname.groups
// { '0': '123' }
1
2
3

上面示例中,(\\d+)是一个组匹配,因为它是第一个组匹配,所以匹配结果放在pathname.groups的属性0。

(7)|

特殊字符|表示左右两侧的字符,都可以出现,即表示逻辑OR。

let pattern = new URLPattern({
  port: "(80|443)",
});
1
2
3

上面示例中,(80|443)表示80或者443都可以。

(8):

特殊字符:用来定义一个具名组匹配,后面跟着变量名。

let pattern = new URLPattern({
  pathname: "/:path",
});
1
2
3

上面示例中,/:path表示斜杠后面的部分,都被捕捉放入变量path,可以从匹配结果的pathname.groups上的对应属性获取。

const pattern = new URLPattern({ pathname: "/books/:id" });

pattern.exec("https://example.com/books/123").pathname.groups
// { id: '123' }
1
2
3
4

上面示例中,pathname.groups返回一个对象,该对象的属性就是所有捕捉成功的组变量,上例是id。

下面是另一个例子。

const pattern = new URLPattern({ pathname: "/:product/:user/:action" });
const result = pattern.exec({ pathname: "/store/wanderview/view" });

result.pathname.groups.product // 'store'
result.pathname.groups.user // 'wanderview'
result.pathname.groups.action // 'view'
result.pathname.input // '/store/wanderview/view'
1
2
3
4
5
6
7

上面示例中,:product、:user、:action的匹配结果,都可以从pathname.groups的对应属性上获取。

组匹配可以放在模式的前面。

const pattern = new URLPattern(
  "/books/:id(\\d+)",
  "https://example.com"
);
1
2
3
4

上面示例中,组匹配:id后面跟着模型定义\\d+,模式需要放在括号里面。

(9)特殊字符转义

如果要将特殊字符当作普通字符使用,必须在其前面加入双重反斜杠进行转义。

let pattern1 = new URLPattern({
  pathname: "/a:b",
});

let pattern2 = new URLPattern({
  pathname: "/a\\:b",
});
1
2
3
4
5
6
7

上面示例中,a:b表示路径以字符a开头,后面的部分都放入变量b。而a\\:b表示路径本身就是a:b就是。

# 实例属性

URLPattern 实例的属性对应URLPattern()模式对象参数的各个部分。

const pattern = new URLPattern({
  hostname: "{*.}?example.com",
});

pattern.hostname // '{*.}?example.com'
pattern.protocol // '*'
pattern.username // '*'
pattern.password // '*'
pattern.port // ""
pattern.pathname // '*'
pattern.search // '*'
pattern.hash // '*'
1
2
3
4
5
6
7
8
9
10
11
12

上面示例中,pattern是一个实例对象,它的属性与URLPattern()的参数对象的属性一致。

注意,search不包括开头的?,hash不包括开头的#,但是pathname包括开头的/。

下面是另一个例子。

const pattern = new URLPattern("https://cdn-*.example.com/*.jpg");

pattern.protocol // 'https'
pattern.hostname // 'cdn-*.example.com'
pattern.pathname // '/*.jpg'
pattern.username // ''
pattern.password // ''
pattern.search // ''
pattern.hash // ''
1
2
3
4
5
6
7
8
9

# 实例方法

# exec()

实例的exec()方法,把模式用于解析参数网址,返回匹配结果。

exec()方法的参数与new URLPattern()是一致的。它可以是一个 URL 字符串。

pattern.exec("https://store.example.com/books/123");
1

如果第一个参数是相对 URL,那么需要基准 URL,作为第二个参数。

pattern.exec("/foo/bar", "https://example.com/baz");
1

exec()方法的参数,也可以是一个对象。

pattern.exec({
  protocol: "https",
  hostname: "store.example.com",
  pathname: "/books/123",
});
1
2
3
4
5

如果匹配成功,它返回一个包括匹配结果的对象。如果匹配失败,返回null。

const pattern = new URLPattern("http{s}?://*.example.com/books/:id");
pattern.exec("https://example.com/books/123") // null
1
2

上面示例中,匹配失败返回null。

匹配成功返回的对象,有一个inputs属性,包含传入pattern.exec()的参数数组。其他属性的值也是一个对象,该对象的input属性对应传入值,groups属性包含各个组匹配。

const pattern = new URLPattern("http{s}?://*.example.com/books/:id");
let match = pattern.exec("https://store.example.com/books/123");

match.inputs // ['https://store.example.com/books/123']
match.protocol // { input: "https", groups: {} }
match.username // { input: "", groups: {} }
match.password // { input: "", groups: {} }
match.hostname // { input: "store.example.com", groups: { "0": "store" } }
match.port // { input: "", groups: {} }
match.pathname // { input: "/books/123", groups: { "id": "123" } }
match.search // { input: "", groups: {} }
match.hash // { input: "", groups: {} }
1
2
3
4
5
6
7
8
9
10
11
12

# test()

实例的test()方法,用来检测参数网址是否符合当前模式。

它的参数跟URLPattern()是一样的,可以是模式字符串,也可以是模式对象。

const pattern = new URLPattern({
  hostname: "example.com",
  pathname: "/foo/*"
 });

pattern.test({
  pathname: "/foo/bar",
  baseURL: "https://example.com/baz",
}) // true

pattern.test("/foo/bar", "https://example.com/baz") // true
1
2
3
4
5
6
7
8
9
10
11

正常情况下,它返回一个布尔值。但是,如果语法不合法,它也会抛错。

pattern.test({ pathname: "/foo/bar" }, "https://example.com/baz") // 报错
1
编辑 (opens new window)
上次更新: 2024/9/6 12:14:45
url
urlsearchparams

← url urlsearchparams→

最近更新
01
IoC 解决了什么痛点问题?
03-10
02
如何调试 Nest 项目
03-10
03
Provider注入对象
03-10
更多文章>
Copyright © 2019-2025 Study | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式