44

I've been searching all over for an answer to this and all of the answers I've found haven't been in JavaScript.

I need a way, in javascript, to check if a string starts with http, https, or ftp. If it doesn't start with one of those I need to prepend the string with http://. indexOf won't work for me I don't think as I need either http, https or ftp. Also I don't want something like google.com/?q=http://google.com to trigger that as being valid as it doesn't start with an http whereas indexOf would trigger that as being true (if I'm not entirely mistaken).

The closest PHP regex I've found is this:

function addhttp($url) {
   if (!preg_match("~^(?:f|ht)tps?://~i", $url)) {
      $url = "http://" . $url;
   }
   return $url;
}

Source: How to add http if its not exists in the url

I just don't know how to convert that to javascript. Any help would be greatly appreciated.

Community
  • 1
  • 1
Peter
  • 3,144
  • 11
  • 37
  • 56
  • Shamefully confusion of javascript and java deleted – Foon Jul 02 '12 at 20:48
  • possible duplicate of [Regular expression for browser Url](http://stackoverflow.com/questions/2899454/regular-expression-for-browser-url) – Hamish Jul 02 '12 at 20:49

7 Answers7

110
export const getValidUrl = (url = "") => {
    let newUrl = window.decodeURIComponent(url);
    newUrl = newUrl.trim().replace(/\s/g, "");

    if(/^(:\/\/)/.test(newUrl)){
        return `http${newUrl}`;
    }
    if(!/^(f|ht)tps?:\/\//i.test(newUrl)){
        return `http://${newUrl}`;
    }

    return newUrl;
};

Tests:

expect(getValidUrl('https://www.test.com')).toBe('https://www.test.com');
expect(getValidUrl('http://www.test.com')).toBe('http://www.test.com');
expect(getValidUrl('    http   :    /  /  www.test.com')).toBe('http://www.test.com');
expect(getValidUrl('ftp://www.test.com')).toBe('ftp://www.test.com');
expect(getValidUrl('www.test.com')).toBe('http://www.test.com');
expect(getValidUrl('://www.test.com')).toBe('http://www.test.com');
expect(getValidUrl('http%3A%2F%2Fwww.test.com')).toBe('http://www.test.com');
expect(getValidUrl('www    .  test.com')).toBe('http://www.test.com');
GROVER.
  • 4,071
  • 2
  • 19
  • 66
user123444555621
  • 148,182
  • 27
  • 114
  • 126
  • 7
    I would recommend adding check for 'url' value in order to avoid returning 'http://' when no value (or empty) string is provided: if (url && !/^(f|ht)tps?:\/\//i.test(url)) – Denys Vuika Feb 02 '14 at 15:56
  • I always get "undefined" back. Can you provide a codepen or jsfiddle? – Black May 07 '18 at 11:06
40

This should work:

var pattern = /^((http|https|ftp):\/\/)/;

if(!pattern.test(url)) {
    url = "http://" + url;
}

jsFiddle

tskuzzy
  • 35,812
  • 14
  • 73
  • 140
20
var url = "http://something.com"
if( url.indexOf("http") == 0 ) {
    alert("yeah!");
} else {
    alert("No no no!");
}
nicowernli
  • 3,250
  • 22
  • 37
5

Non-Regex declarative way:

const hasValidUrlProtocol = (url = '') => 
    ['http://', 'https://', 'ftp://'].some(protocol => url.startsWith(protocol))
Shota
  • 6,910
  • 9
  • 37
  • 67
  • This is a good answer! +1 for declarative! But do you need the `Boolean` here? Doesn't `.some()` return a boolean already? – emersonthis Apr 02 '21 at 14:19
3

This should work:

var re = /^(http|https|ftp)/
elclanrs
  • 92,861
  • 21
  • 134
  • 171
3

Refining previous answers a bit more, I used new RegExp(...) to avoid messy escapes, and also added an optional s.

var pattern = new RegExp('^(https?|ftp)://');

if(!pattern.test(url)) {
    url = "http://" + url;
}

var pattern = new RegExp('^(https?|ftp)://');


console.log(pattern.test('http://foo'));
console.log(pattern.test('https://foo'));
console.log(pattern.test('ftp://foo'));
console.log(pattern.test('bar'));
Steven Spungin
  • 27,002
  • 5
  • 88
  • 78
0

Best readability I'd say is to use .startsWith('theString').

The code below checks for both http://, https:// and ftp:// and sets okUrl to a boolean true if any of them comply, by using the || which means or.

When you know if the url contains none of those strings, then just just add http:// to the start of the string either with literals (${})

let url = 'google.com'
const urlOK = url.startsWith('http://') || url.startsWith('https://') || url.startsWith('ftp://')


if (!urlOk) url = `http://${url}`
// => 'http://google.com'

or with simple string concat, which can be done in various ways, for example:

url = 'http://' + url

Read more about it, and test it, here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith

Christoffer
  • 475
  • 4
  • 9