new URL() - WHATWG URL API

34

我正在使用node进行实验,想要获取URL类的一个实例(由于其便捷的属性),就像这样:

const { URL } = require('url');
(...)
http.createServer((request,response) => {
    let uri = new URL(request.url);
    (...)
}

但它失败了

TypeError [ERR_INVALID_URL]: Invalid URL: /

这很有趣,因为

const url = require('url');
url.parse();

工作,所以我对它很好奇。我理解这种后来的方法比较旧。

我在本地开发,所以为了发送请求,我在浏览器中使用localhost:8000。

如何使用request中的信息实例化一个新的URL对象?

我已经查过的信息和东西:

node -v
v9.3.0

https://nodejs.org/api/url.html#url_class_url
https://dev59.com/cVcP5IYBdhLWcg3wNnfW
https://stackoverflow.com/questions/45047840/in-node-js-how-to-get-construct-url-string-from-whatwg-url-including-user-and-pa
https://stackoverflow.com/questions/47481784/does-url-parse-protect-against-in-a-url
https://dev59.com/72Qm5IYBdhLWcg3w-jBL

2
错误提示了问题所在。'/'是无效的URL格式。'/'是一个路径。为了成为有效的URL,它需要一个主机、协议和路径。 - Paul
1个回答

38

正如Joshua Wise在Github(https://github.com/nodejs/node/issues/12682)上指出的那样,问题在于request.url不是绝对URL,它可以用作路径或相对URL,但缺少主机和协议。

根据API文档,您可以通过提供基础URL作为第二个参数来构造有效的URL。但这仍然很麻烦,因为从request.headers中不容易获得协议。我简单地假定使用HTTP:

var baseURL = 'http://' + request.headers.host + '/';
var myURL = new URL(request.url, baseURL);

这显然不是一个理想的解决方案,但至少你可以利用查询字符串解析。例如,

URL {
  href: 'http://localhost:8080/?key1=value1&key2=value2',
  origin: 'http://localhost:8080',
  protocol: 'http:',
  username: '',
  password: '',
  host: 'localhost:8080',
  hostname: 'localhost',
  port: '8080',
  pathname: '/',
  search: '?key1=value1&key2=value2',
  searchParams: URLSearchParams { 'key1' => 'value1', 'key2' => 'value2' },
  hash: '' }

我喜欢你的解决方案。我们可以将baseURL字符串构建抽象为一个函数,该函数可以确定协议,是吗? - Thom
1
如何将基本URL制作成示例,以表明它是必需的但仍然是示例?示例:'example://example.test'。注意:要保留末尾斜杠以便从相对URL中解析出pathname。然后可以更轻松地验证pathname的相对性质(第一个或前几个字符)。除非相对URL的协议提供了可接受的源,否则.origin将为null。好处是没有Request的隐藏依赖性,同时仍适用于IANA / RFC符合性,而URI方案不会误导(在Node URL中被错误命名为protocol)。 - hakre

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