3

I would like a function in javascript that will get as a parameter an url and will return the port of that URL as it follows:

  • If there's a http or https (port 80 / 443) it won't be shown in url structure but I want them returned anyway.
  • If there's another port, I want that to be returned.

Example:

function myFunction(url){
    something here
    ...
    return port
}

I've seen that this can be done easy using some additional libraries but I do not want to use one. I didn't work with js since now and I would really appreciate if somebody will also be able to explain his solution.

Salman A
  • 262,204
  • 82
  • 430
  • 521
Cajuu'
  • 1,154
  • 2
  • 19
  • 50
  • I am using it in the browser and I already have that URL as a string, so I don't want to get it from anywhere else. I only want the function explained if possible – Cajuu' Apr 24 '15 at 06:02
  • 1
    There are other ways to simply fetch `port` and `protocal` from URL such as `window.document.location.port` and `window.document.location.protocol` or simply `location.port` and `location.protocal` – Zee Apr 24 '15 at 06:06
  • The way you worded the question is kind of confusing. It might help to add some example input/output. – Useless Code Apr 24 '15 at 06:53

3 Answers3

5

From what I get, you don't want to use location as the URL to subtract the port from, just any string as an URL. Well, I came up with this, for such a case. This function takes any string (but you can pass it the location URL anyway, and it works the same):

function getPort(url) {
    url = url.match(/^(([a-z]+:)?(\/\/)?[^\/]+).*$/)[1] || url;
    var parts = url.split(':'),
        port = parseInt(parts[parts.length - 1], 10);
    if(parts[0] === 'http' && (isNaN(port) || parts.length < 3)) {
        return 80;
    }
    if(parts[0] === 'https' && (isNaN(port) || parts.length < 3)) {
        return 443;
    }
    if(parts.length === 1 || isNaN(port)) return 80;
    return port;
}
  • It gets the base url from the string.
  • It splits the base url into parts, by ':'.
  • It tries to parse the digits-only part of the port (the last element of the parts array) into an integer.
  • If the URL starts with 'http' AND the port is not a number or the length of the URL parts array is less than 3 (which means no port was implied in the URL string), it returns the default HTTP port.
  • Same thing goes for 'https'.
  • If the length was 1, it means no protocol nor port was provided. In that case or in the case the port is not a number (and again, no protocol was provided), return the default HTTP port.
  • If it passes through all these tests, then it just returns the port it tried to parse into an integer at the beginning of the function.
  • 1
    No problem. Let us know if any issues arise (and also if none do!). –  Apr 24 '15 at 07:09
  • 1
    I tried it out and it works for http and https but when I add a link as `http://www.something.com:88/something?id=test` it just puts an `1` at the end of the port so the resulted output will be: `881` instead of 88. Any hints – Cajuu' Apr 24 '15 at 07:30
  • It works perfect. But have in mind another scenario: supposing we have an URL like this:`https://www.get.example.com:1343/elance?something=123?id:1` or `https://www.get.example.com:1343/elance?something=123?id:1&name:5` I will get some strange outputs like: `1` for the first one and `1` for the second . How could this be handled ? – Cajuu' Apr 24 '15 at 07:49
  • 1
    Alright, thanks for pointing that out. I updated the code. I think that scenario is now covered :p. If the length of the `parts` array exceeds 3, it takes the element at index `2`, if not, it takes the last element. I also updated the regex a bit (as compared to the last one). This should work well. –  Apr 24 '15 at 08:08
  • 1
    In fact I have just come across with another scenario: what if: `https://www.get.example.com/elance?something=123?id:135456&something:15` ? It should return `443` but it returns `135456` ? – Cajuu' Apr 24 '15 at 08:16
  • 1
    Just updated the code. That scenario is now covered. I think I can still clean-up the code, though. Can think of any other? Haha. –  Apr 24 '15 at 08:38
  • Didn't come across with anything else. Will keep you posted if there's another find-out. Thanks :D – Cajuu' Apr 24 '15 at 08:39
  • Alright then, I'll be around. No problem. Good luck :) –  Apr 24 '15 at 09:22
  • I just edited it a little bit more, it didn't work well when the URL didn't have a '/' at the end, but had a protocol specified. –  Apr 24 '15 at 09:22
1

Here is a regex based solution (the regex is not bullet proof):

var urls = [
  "http://localhost/path/",
  "https://localhost/",
  "http://localhost:8080",
  "https://localhost:8443/path",
  "ftp://localhost/"
];
var i;
for (i = 0; i < urls.length; i++) {
  console.log(urls[i], getPortFromURL(urls[i]));
}

function getPortFromURL(url) {
  var regex = /^(http|https):\/\/[^:\/]+(?::(\d+))?/;
  var match = url.match(regex);
  if (match === null) {
    return null;
  } else {
    return match[2] ? match[2] : {http: "80", https: "443"}[match[1]];
  }
}
<!-- nothing here, see console -->
Salman A
  • 262,204
  • 82
  • 430
  • 521
-1

hope the following code will help

function getPort(){
var port==location.port;
if(port=="")
{
if(location.protocol=="http:")
  return "80";
else
  return "443";
return port;
}