Check if a JavaScript string is a URL

前端 未结 30 3388
野趣味
野趣味 2020-11-22 15:41

Is there a way in JavaScript to check if a string is a URL?

RegExes are excluded because the URL is most likely written like stackoverflow; that is to s

30条回答
  •  自闭症患者
    2020-11-22 16:34

    This seems to be one of the hardest problems in CS ;)

    Here's another incomplete solution that works well enough for me and better than the others I've seen here. I'm using a input[type=url] for this in order to support IE11, otherwise it would be much simpler using window.URL to perform the validation instead:

    const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
    function isValidIpv4(ip) {
      if (!ipv4Regex.test(ip)) return false;
      return !ip.split('.').find(n => n > 255);
    }
    
    const domainRegex = /(?:[a-z0-9-]{1,63}\.){1,125}[a-z]{2,63}$/i;
    function isValidDomain(domain) {
      return isValidIpv4(domain) || domainRegex.test(domain);
    }
    
    let input;
    function validateUrl(url) {
      if (! /^https?:\/\//.test(url)) url = `http://${url}`; // assuming Babel is used
      // to support IE11 we'll resort to input[type=url] instead of window.URL:
      // try { return isValidDomain(new URL(url).host) && url; } catch(e) { return false; }
      if (!input) { input = document.createElement('input'); input.type = 'url'; }
      input.value = url;
      if (! input.validity.valid) return false;
      const domain = url.split(/^https?:\/\//)[1].split('/')[0].split('@').pop();
      return isValidDomain(domain) && url;
    }
    
    console.log(validateUrl('google'), // false
      validateUrl('user:pw@mydomain.com'),
      validateUrl('https://google.com'),
      validateUrl('100.100.100.100/abc'),
      validateUrl('100.100.100.256/abc')); // false

    In order to accept incomplete inputs such as "www.mydomain.com" it will also make it valid assuming the protocol is "http" in those cases and returning the valid URL if the address is valid. It returns false when invalid.

    It also supports IPv4 domains, but not IPv6.

提交回复
热议问题