如何操作URL_JavaScript中URL对象如何解析和构建

URL构造函数可解析protocol、hostname、pathname、search、hash等只读属性,要求输入为完整合法URL(含协议和主机),否则报错;相对路径需提供base URL;修改查询参数须用URLSearchParams。

URL 构造函数能解析哪些部分

JavaScript 的 URL 构造函数会把传入的字符串按标准 URL 格式拆解成多个只读属性,比如 protocolhostnamepathnamesearchhash 等。它要求输入必须是**完整且语法合法的 URL**(即至少含协议和主机名),否则抛出 TypeError: Invalid URL

  • new URL("https://example.com/path?k=v#section") ✅ 成功
  • new URL("/path?k=v") ❌ 报错:缺少协议和主机
  • new URL("example.com/path") ❌ 报错:不是有效 URL(没协议)

如果只有相对路径,得手动补上基础 URL 才能解析:new URL("/path?k=v", "https://a.b") → 主机变为 a.b,路径为 /path

修改 search 参数要用 URLSearchParams

URL 对象的 search 属性是只读字符串(如 "?a=1&b=2"),不能直接拼接或正则替换。真正安全、可维护的做法是用 URLSearchParams 实例操作参数:

const url = new URL("https://api.example.com/data?limit=10");
url.searchParams.set("offset", "20");
url.searchParams.append("sort", "desc");
console.log(url.href); // https://api.example.com/data?limit=10&offset=20&sort=desc
  • set(key, value) 覆盖已有键(只保留一个)
  • append(key, value) 总是新增,支持重复键(如 ?tag=a&tag=b
  • delete(key) 移除所有匹配键值对
  • 直接赋值 url.search = "?x=1" 会重置整个查询串,但丢失原有参数结构逻辑

构建 URL 时 protocol 和 hostname 不能省略

即使目标是同源请求,也不能靠省略协议或主机来“简化”构造。下面这些写法都无效:

  • new URL("//api.example.com/v1", location) → 协议未继承,报错
  • new URL("/v1?x=1", "example.com") → 主机字符串缺协议,报错
  • new URL("/v1", location.origin) ✅ 正确:以当前页面 origin 为 base

常见安全做法是显式使用 location.origin 或已知可信的 https://... 字符串作 base,避免因 base 不合法导致整个 URL 构造失败。

注意 pathname 的开头斜杠和编码行为

URL.pathname 始终以 / 开头(即使是根路径 /),且自动对路径中非 ASCII 字符或特殊符号做百分号编码:

const u = new URL("https://x.y/z 三/α?k=1");
console.log(u.pathname); // "/z%20%E4%B8%89/%CE%B1"
console.log(u.search);  // "?k=1"
  • 手动设置 url.pathname = "/user/张" 会被自动编码为 /user/%E5%BC%A0
  • 若需保持原始字符串不做编码,只能拼接在 href 上(但失去结构化优势)
  • 路径末尾多斜杠(如 //api//v1/)会被规范为单斜杠(/api/v1/

路径解析依赖浏览器的 URL 标准实现,不同环境(如某些 Node.js 版本)对边缘 case 处理略有差异,生产中建议始终用 URL + URLSearchParams 组合,别手写字符串拼接。