express icon indicating copy to clipboard operation
express copied to clipboard

Request: Introduce a `req.completeURL()` method

Open pmorch opened this issue 2 years ago • 3 comments

When communicating with other systems, sometimes we need to send the complete URL. E.g. include the full http://localhost:30000/foo?a=45 in the response when accessing that URL.

req.originURL becomes /foo?a=45, but the scheme and hostname parts are lost.

node.js - How to get the full URL in Express? - Stack Overflow has 578 upvotes and the top answer has 871 upvotes. But there are also a gazillion other answers of varying correctness.

The suggestion from the top answer is:

var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;

Could we "officialize" this and turn it into req.completeUrl() (or whatever name you prefer) so everybody uses the same solution that works reliably? I'm happy to create a PR for this one-liner, I just wanted to ask here first...

pmorch avatar Sep 12 '21 05:09 pmorch

Hi @pmorch thanks for the suggestion! We can certainly consider this request, though it is tricky to add new helpers to req or res without a major version change due to existing applications possibility already providing those. In the meantime, you can add this functionality to your own applications like the following:

app.request.completeUrl = () => `${this.protocol}://${this.get('host')}${this.originalUrl}`

As for your oneliner, it may work fine for your application, but would need to be made robust for an implementation that would land in Express, it that is desired. For example, some parts of your oneliner take into account the trust proxy setting, but not others, the req.originalUrl may be a fully-qualified URL if the client sent the entire URL as the request-target, req.originalUrl may not exist in all locations in which a req helper may be called from, among other issues.

dougwilson avatar Sep 12 '21 05:09 dougwilson

@dougwilson writes:

it may work fine for your application, but would need to be made robust for an implementation that would land in Express

Which is exactly why this should be in express and not cut'n'pasted from stackoverflow, where it works 60% of the time.

pmorch avatar Sep 12 '21 08:09 pmorch

Hi, I am unable to get the complete URL using this. var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;

suppose I am calling this on route /getUrl

I should get http://<server_ip>/app/users/happy/getUrl

instead I only get http://<server_ip>/getUrl

I am using Nginx as a reverse proxy.

location /app/users/happy/ {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-NginX-Proxy true;
      proxy_pass http://localhost:4216/;
      proxy_ssl_session_reuse off;
      proxy_set_header Host $http_host;
      proxy_cache_bypass $http_upgrade;
      proxy_set_header X-Forwarded-Host $http_host;
      proxy_set_header X-Forwarded-Server $http_host;
      proxy_redirect ~/(.*)$ /app/users/happy/$1;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "Upgrade";
    }

I also tried adding app.set('trust proxy', 'loopback');

rhutikcodes avatar Nov 19 '21 05:11 rhutikcodes