Node的url.format已经被弃用,我们应该使用什么替代品?

8

我在 VS Code 中收到警告,说来自 NodeJS URL 模块的 url.format 已经被弃用。

const nodeUrl = require('url')

const url = nodeUrl.format({
  protocol: 'https',
  host: 'example.com',
  pathname: 'somepath'
})

我应该使用什么替代?只是将上述内容进行替换是完全安全的吗?
const buildUrl = (url) => url.protocol + '://' + url.host + '/' + url.pathname


这两个函数等效吗?也就是说,对于任何具有该结构的对象输入,它会产生相同的输出吗?url.format没有任何我可能错过的魔法吗?例如,带有或不带有前导/pathname

我的项目很大,有很多调用url.format的地方,我想确保没有任何问题。

编辑:显然,我们应该使用 WHATWG URL标准

那么这是正确的替换吗?

const buildUrl = (url) => new URL(url.pathname, url.protocol + '://' + url.host)

如果您查看警告的来源类型,废弃提示所示的方法是使用带有“URL”而非“vanilla object”的形式。 - jonrsharpe
@jonrsharpe 什么是 WHATWG URL API - João Pimentel Ferreira
https://nodejs.org/api/url.html#the-whatwg-url-api,https://url.spec.whatwg.org/ - jonrsharpe
2
为了澄清上面的评论,您在文档中链接的内容不是已弃用的形式,这就是为什么它没有建议使用替代方法。https://nodejs.org/api/url.html#urlformaturlobject 是您正在调用的内容,https://nodejs.org/api/url.html#urlformaturl-options 是您应该使用的内容。 - jonrsharpe
1
@jonrsharpe非常感谢,但我仍然不清楚如何使用WHATWG API替换url.format(urlObject)?只需要new URL(urlObject.pathname, urlObject.protocol + '://' + urlObject.host)吗? - João Pimentel Ferreira
显示剩余3条评论
2个回答

2
请查看URL文档,并注意某些属性(如host(包括port)和hostname(不包括))之间的区别。根据您问题中的组件,似乎需要使用以下函数,您可以根据自己的需求进行扩展:

function urlFromComponents ({pathname = '/', protocol = 'https:', ...props} = {}) {
  const url = new URL('https://site.example');
  url.protocol = protocol;
  url.hostname = props.hostname;
  url.pathname = pathname;
  return url;
}

const protocol = 'https';
const hostname = 'example.com';
const pathname = 'somepath';

const url1 = urlFromComponents({
  hostname,
  pathname, // pathname will have "/" prepended if absent
  protocol, // protocol actually ends in ":", but this will also be fixed for you
});

const url2 = urlFromComponents({hostname, pathname});

console.log({url1, url2});


非常感谢,但请检查我的答案,它更加通用 :) - João Pimentel Ferreira

0

Node指的是将urlObject作为输入的url.format方法已被弃用,尽管它仍然是一个稳定的解决方案。

enter image description here

我们现在应该使用 WHATWG URL API。请注意,使用require('url')获取的url模块提供了两个API来处理URL:一个是Node.js特定的遗留API,另一个是实现了与Web浏览器相同的WHATWG URL标准的新API。
尝试使用新的WHATWG URL标准构造函数来模拟旧的url.format方法API的一种解决方案可能是一行代码。
const urlFrom = (urlObject) => String(Object.assign(new URL("http://a.com"), urlObject))

在这里进行测试

const urlFrom = (urlObject) => String(Object.assign(new URL("http://a.com"), urlObject))

const url1 = urlFrom({
  protocol: 'https',
  hostname: 'example.com',
  pathname: 'somepath'
})
console.log('url1:', url1) // https://example.com/somepath

const url2 = urlFrom({
  protocol: 'https:',
  host: 'example.com',
  pathname: '/somepath'
})
console.log('url2:', url2) // https://example.com/somepath

const url3 = urlFrom({
  protocol: 'https:',
  host: 'example.com:8080',
  pathname: '/somepath'
})
console.log('url3:', url3) // https://example.com:8080/somepath

const url4 = urlFrom({
    protocol: 'http:',
    hostname: 'example.com',
    port: 8080,
    pathname: '/somepath'
  })
console.log('url4:', url4) // http://example.com:8080/somepath

const url5 = urlFrom({
    protocol: 'https:',
    hostname: 'example.com',
    port: 8080,
    pathname: '/somepath',
    username: 'john',
    password: 'abc',
    search: 'item=bike'
  })
console.log('url5:', url5) // https://john:abc@example.com:8080/somepath?item=bike


该解决方案的问题在于它不支持查询参数:/ - aapzu
我认为这是正确的解决方案。查询参数在“pathname”键中,所以没问题。我不喜欢的是“new URL(someString)”实例,但我找不到其他方法来做到这一点。 - loretoparisi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接