67

require('url').parse('someurl.com/page') have been docs-only deprecated, and our strict linter is unhappy about it... I have tried to replace it in our code with what the internet suggests new URL('someurl.com/page') which works in most cases.

However, we have examples where the url is a local image some/image.png and that was working nicely with url.parse() and returns:

Url {
  protocol: null,
  slashes: null,
  auth: null,
  host: null,
  port: null,
  hostname: null,
  hash: null,
  search: null,
  query: null,
  pathname: '/some/image.png',
  path: '/some/image.png',
  href: '/some/image.png'
}

But the suggested replacement new URL('some/image.png') throws a type error...

TypeError [ERR_INVALID_URL] [ERR_INVALID_URL]: Invalid URL: /some/image.png

url.parse is doing some validation and accept local paths, but the new url constructor does not. What to do ?

7 Answers 7

38
const server = http.createServer((req, res) => {
   const baseURL =  req.protocol + '://' + req.headers.host + '/';
   const reqUrl = new URL(req.url,baseURL);
   console.log(reqUrl);
});

will give reqUrl :

URL {
  href: 'http://127.0.0.1:3000/favicon.ico',
  origin: 'http://127.0.0.1:3000',
  protocol: 'http:',
  username: '',
  password: '',
  host: '127.0.0.1:3000',
  hostname: '127.0.0.1',
  port: '3000',
  pathname: '/favicon.ico',
  search: '',
  searchParams: URLSearchParams {},
  hash: ''
}
Sign up to request clarification or add additional context in comments.

3 Comments

baseURL = req.protocol + '://' + req.headers.host + '/'; would probably be more correct, as request could actually be https.
the req.protocol is undefined
use 'https' instead of req.protocol
17

You can use the base parameter of the URL constructor. For example:

new URL('some/image-png', "https://dummyurl.com")

For more info, https://nodejs.org/api/url.html#url_constructor_new_url_input_base.

4 Comments

But I need an API that does not require me to know the domain name ;c. I don't want to rely on hardcode or environment variables for such task.
Even though I know that it's not really a URL when you don't have the base, I wonder why they don't provide an alternative other than using a fake dummy website.
@Klesun the input base is optional.See my answer stackoverflow.com/a/73914067/2441641
9

This is how to get the query string params without using any external modules

const http = require("http");

const server = http.createServer((req, res) => {
  const url = new URL(req.url, `http://${req.headers.host}/`);

  const query = new URLSearchParams(url.search);
  console.log(query.entries());

  res.end("I am done");
});

server.listen(3000);

1 Comment

This approach matches the usage example in nodejs documentation, though the authors do admit that it's "not a particularly elegant one".
7
const path = require("path");
const url = require("url");

const p = path.join("public", "images", "a.jpg");

console.log(p);                                     // public\images\a.jpg
console.log(new url.URL(p, "http://xxx").pathname); // /public/images/a.jpg

Comments

1

Simply use new URL to parse get all data:

const server = http.createServer((req, res) => {
   const parsedUrl = new URL(req.url, `https://${req.headers.host}/`);
   console.log(parsedUrl);
});

And parsedUrl will consist all URL's data:

{
  href: 'https://localhost:5000/getIPData/?param=value',
  origin: 'https://localhost:5000',
  protocol: 'https:',
  username: '',
  password: '',
  host: 'localhost:5000',
  hostname: 'localhost',
  port: '5000',
  pathname: '/getIPData/',
  search: '?param=value',
  searchParams: URLSearchParams { 'param' => 'value' },
  hash: ''
}

Use http or https prefix depending on your protocol.

By the way, for getting query params values use:

parsedUrl.searchParams.get('param')

Comments

0

In my case, at first

import url from 'url';
const {query, pathname} = url.parse(req.url);

they show me url.parse is deprecated.

const {query, pathname} = url.parse(req.url, true);

It work for me, I forgot the boolean flag.

Comments

-1

On Node v16.17.1.

This is what works for me:

const { URL } = require('url');

const url = new URL('https://somewebsite.com/params?x=x')

1 Comment

For those that down voted this answer, check your Node version first. It is clearly stated that this works on Node.js v16 and the question was asked many many years ago.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.