With HTML5 url input validation assume url starts with http://
Asked Answered
C

9

34

HTML5 provides for automatic URL validation :-

<form>
   <input type="url" name="someUrl">
</form>

This will fail validation for URL's that don't have a protocol prefix - e.g. stackoverflow.com will fail while http://stackoverflow.com will pass.

How can I automatically add http:// to a url if there isn't already a protocol?

I could add a onblur event handler but is there a better way like some before validation event?

Crinkle answered 30/7, 2013 at 12:23 Comment(5)
Perhaps a bit pendantic but stackoverflow.com really isnt a URL. It's just a host name...Forefront
True - but pedantic ;) The average person seeing a form with a "Website" label just can't be bothered with the difference between stackoverflow.com and http: // stackoverflow.com'Crinkle
In defense of mr. Average Person: most browsers actually hide the "http://" part of the URL.Vulnerable
The cleaner way would be to prepend http during form submission. Form onsubmit event.Ebsen
Also, http URLs are just one kind of URL. ftp://, ssh://, https://, git:// are all common schemes for URLs. The type="url" input doesn’t accept scheme-less URLs because of that: a scheme-less URL is not a URL and the assumed protocol depends on your application.Theriot
L
25

The code for this should not interrupt the user's action, but should instead wait until the user leaves the form field to check the input text for "http". So use "onblur" instead of "onkeyup".

Then, just see if the string contains "http" using indexOf. If not, it will return -1, which is falsey.

function checkURL (abc) {
  var string = abc.value;
  if (!~string.indexOf("http")) {
    string = "http://" + string;
  }
  abc.value = string;
  return abc
}
<form>
  <input type="url" name="someUrl" onblur="checkURL(this)" />
  <input type="text"/>
</form>

Fiddle

Lifework answered 2/2, 2015 at 17:1 Comment(3)
Doesn't work for e.g. example.com/http. You should use a stricter check, like (string.indexOf("http:") === 0)... or actually, this will make it prepend http:// to https:// urls, so rather (string.match(/^https?:/)) Of course, it'll still prepend it to valid ftp:// urls, etc. so if you want to allow any protocol then it would be (string.match(/^\w+:/))Kiwi
this code is furthermore wrong in case someone just tabs through the input without entering anything. You just use tab to get to the next field, now you have a stupid http:// in the url field you didn't want thereGiltzow
Irrelevant to the issue discussed, but that tilde in !~string.indexOf(...) is very confusing.Nodular
S
10

if you don't want the browser validation (it can vary between browsers) you can add the following novalidate attribute

<input type="url" name="someUrl"  formnovalidate="formnovalidate"> 

else you might want to be more transparent about prefixing http:// by simply adding once someone starts to type or even to have http:// already typed into the box on the page load

(credit to editor who rightly points out that novalidate applies to form, while above overrides that, debit to creditor for approach to edit ;)

Siobhan answered 30/7, 2013 at 12:28 Comment(0)
G
9

what you guys probably want to use is this:

$(function(){
         $('input[type="url"]').on('blur', function(){
           var string = $(this).val();
           if (!string.match(/^https?:/) && string.length) {
             string = "https://" + string;
              $(this).val(string)
           }
         });
});

this runs on document ready

checks if value is empty or has missing http at the beginning

inserts it in that case on blur

thanks @1j01

Giltzow answered 27/9, 2017 at 15:34 Comment(4)
This is the one. Takes care of all of the exceptions noted about the accepted answer. Works perfectly for all of the following: example.com www.example.com http://example.com https://example.com example.com?otherurl=http://foo.bar. Even cases like just entering example becomes http://example which still does not validate, but is still helpful and is the expected result. And the blank value handling is essential and works great.Fredela
Question is related with HTML5, not jQueryServia
This works fine, however, I would recommend it to add https instead of http, to be save ;-).Tega
@JanSalvadorvanderVen - there are still a decent amount of sites out there in the world without security certs that only use http: and most secure sites redirect from http: to https:. Definitely a compromise either way, but it seems better to not break the http sites and to rely on the redirects to https for the other. I would consider switching to https default once global stats are above 95% or so.Fredela
M
6

You can try to force users enter valid url by providing initial value and placeholder.

<label for="some-url">Some url:</label>
<input id="some-url" type="url" placeholder="http://example.com" value="http://">
Mineralogy answered 4/6, 2016 at 8:34 Comment(3)
This is a sure recipe for users who are copy and pasting ending up with http://http://example.comFredela
@Fredela ye but those users should just give up on using the internet.Pence
That's the kind of attitude that makes me flag programmers as "do not hire" no matter how technically talented they are. It's our job to make the web as easy as possible to use for people of all skill levels.Fredela
F
5

you can use

HTML :

<form>
   <input type="url" name="someUrl" onkeyup="checkUR(this)" >
</form>

SCRIPT:

function checkUR(abc){
    string = abc.value
    if(!(/^http:\/\//.test(string))){
        string = "http://" + string;
    }
    abc.value=string
}

example

I hope it will help

Festination answered 30/7, 2013 at 12:42 Comment(1)
All you need is /^https?:/Kiwi
E
4

Using the URL class would be even better.

    function validateUrl(value) {
        try {
            const currentUrl = new URL(value);
            const { protocol } = currentUrl;

            if (protocol !== 'http:' && protocol !== 'https:') {
                currentUrl.protocol = 'http:';
                return currentUrl.toString();
            }
        } catch(e) {
            return `http://${value}`;
        }
    }

The advantage here is that you check for any protocol first. In case the user mistyped the protocol (e.g. htts:), it will be replaced by http:. The answers above would all prepend a new protocol which would result in something like http://htts:. In case there is no protocol it will just prepend http:// in the catch block.

Eratosthenes answered 12/5, 2021 at 8:43 Comment(0)
C
3

It will help users with http prepending annoyance without being intrusive. Just add this JavaScript code to your webpages with type="url" <input> elements, and everything will work automatically.

// Run a callback function after DOM is fully loaded
function domReady(callback) {
    if (document.readyState != "loading") {
        callback();
    } else {
        document.addEventListener("DOMContentLoaded", callback);
    }
}

// Prepend https to url input field value if already not prepended by http or https
domReady(() => {
    const urlInput = document.querySelectorAll('input[type="url"]');
    for(i = 0; i < urlInput.length; i++) {
        urlInput[i].addEventListener('change', function(){
            let urlValue = this.value;
            // If http or https isn't prepended as case insensitive characters and if the input field has any value
            if (!urlValue.match(/^https?:/i) && urlValue.length) {
                urlValue = "https://" + urlValue;
                this.value = urlValue;
            }
        });
    }
});

Advantages

  1. prepending https:// if http or https isn't already prepended in the input field value
  2. prepending https:// even when there is http or https that isn't in the beginning
  3. automatically modifying value after users leave input field
  4. not adding https:// if input field has no value
  5. working in a case insensitive manner
  6. automatically working on all url type input fields without requiring to modify HTML input field elements

Limitations

  1. adding https:// in front of valid urls that start with any schemes other than http or https such as ftp and tel which will cause those valid URLs to not work

PS: If you also want to change http to https, append this else if statement to the last if statement in the previous code.

else if (urlValue.match(/^http:/i)) {
    urlValue = urlValue.replace(/^http:/i, "https:");
    this.value = urlValue;
}
Culex answered 24/4, 2021 at 23:19 Comment(0)
Q
2

One-liner:

<input type="url" onblur="if (!~this.value.indexOf('http')) this.value = 'https://' + this.value">
Quinte answered 26/4, 2021 at 11:49 Comment(0)
S
1

This will prepend the URL before submitted if it does not have a http or https in the URL. It is also case insensitive (the i at the end). I'm also using onchange instead of the other events to account for users pressing the enter key and submitting the form that way.

SCRIPT:

function checkURL(o) {
    if (!/^https?:\/\//i.test(o.value)) {
        o.value = "http://" + o.value;
    }
}

ALTERNATE SCRIPT: (Always correct to "http://")

function checkURL(o) {
    o.value = o.value.replace(/^(https?:\/\/)?/i, "http://");
}

HTML:

<form>
   <input type="url" name="someUrl" onchange="checkURL(this)" >
</form>
Swithbert answered 16/12, 2016 at 22:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.