The reliable way to validate a URL is to parse it and see if parsing succeeds — not to match it against a regular expression. Regexes for URLs either reject valid ones (IPv6 hosts, internationalized domains) or accept broken ones. Here’s the parse-based approach in three languages.
Modern JavaScript has URL.canParse(), which returns a boolean. Where it isn’t available, wrap new URL() in try/catch — if construction throws, the URL is invalid:
// Modern
URL.canParse('https://example.com/path'); // true
URL.canParse('not a url'); // false
// Compatible fallback
function isValidUrl(s) {
try { new URL(s); return true; }
catch { return false; }
}
Parsing accepts any valid URL, including javascript: and file:. If you only want web URLs, check the protocol after parsing:
function isHttpUrl(s) {
let u;
try { u = new URL(s); } catch { return false; }
return u.protocol === 'http:' || u.protocol === 'https:';
}
urlparse doesn’t throw on a bad URL, so validate by checking that the required components are present:
from urllib.parse import urlparse
def is_valid_http_url(s):
try:
u = urlparse(s)
except ValueError:
return False
return u.scheme in ('http', 'https') and bool(u.netloc)
is_valid_http_url('https://example.com') # True
is_valid_http_url('example.com') # False (no scheme)
is_valid_http_url('javascript:alert(1)') # False (scheme not http/https)
Prefer java.net.URI for validation (it’s stricter and doesn’t trigger network resolution); a URISyntaxException means the string is malformed:
import java.net.URI;
import java.net.URISyntaxException;
static boolean isValidHttpUrl(String s) {
try {
URI u = new URI(s);
String scheme = u.getScheme();
return u.getHost() != null &&
("http".equals(scheme) || "https".equals(scheme));
} catch (URISyntaxException e) {
return false;
}
}
URLs allow IPv6 hosts (http://[::1]/), internationalized domains, embedded credentials, unusual ports, and more. A single regex almost always gets some of these wrong — rejecting valid URLs or waving through broken ones. The URL parser in your language already implements the standard correctly, so use it.
Two things a syntax check does not do:
127.0.0.1, cloud metadata endpoints). Block internal ranges explicitly.Our decode-then-validate guide covers hardening user-supplied URLs. To check a single URL by hand, the URL validator gives a clear valid/invalid verdict with the reason.
Written and maintained by the urlencodedecode.com team. Every technical claim on this page is verified against primary sources — the RFCs (3986, 3629, 4648, 7578), the WHATWG URL Standard, and official vendor or language documentation — rather than second-hand summaries. When a source contradicts a common assumption, we follow the source and note the discrepancy. Corrections: contactus@urlencodedecode.com.
Parse it rather than matching a regex. In JavaScript use URL.canParse(s) or wrap new URL(s) in try/catch. In Python check urlparse(s) has a scheme and netloc. In Java construct a java.net.URI and catch URISyntaxException. Parsing implements the URL standard correctly where regexes don't.
URLs allow IPv6 hosts, internationalized domains, embedded credentials, and unusual ports, so a single regex almost always rejects valid URLs or accepts malformed ones. The built-in URL parser already implements the standard, so it's far more reliable.
After parsing, check the scheme/protocol. In JavaScript, new URL(s).protocol should equal 'http:' or 'https:'. In Python, urlparse(s).scheme should be 'http' or 'https'. Parsing alone accepts any scheme, including javascript: and file:, so this extra check matters.
No. A syntactically valid URL can still point to a phishing site (open redirect) or an internal address (SSRF). Validate against an allowlist of trusted hosts before redirecting, and block internal IP ranges before your server fetches a user-supplied URL.
Construct a java.net.URI from the string and catch URISyntaxException for malformed input, then check getHost() is non-null and the scheme is http or https. URI is preferred over the older URL class because it validates syntax without triggering network resolution.