How to test if a URL string is absolute or relative?

后端 未结 16 1301
甜味超标
甜味超标 2020-11-29 20:05

How can I test a URL if it is a relative or absolute path in Javascript or jQuery? I want to handle accordingly depending if the passed in URL is a local or external path.

相关标签:
16条回答
  • 2020-11-29 20:45

    You can use a try, catch block to help with this. Rather than using a regular expression, you can use the URL interface at every step.

    isExternalUrl (urlString) {
      try {
        const url = new URL(urlString) // THROW ON MISSING SCHEME
    
        // DOES THIS URL ORIGINATE FROM THIS WEBSITE?
        if (url.origin !== new URL(document.URL, document.baseURI).origin) {
          return true // IS EXTERNAL URL
        }
      } catch (_e) {
        // THROWS WHEN URL DOES NOT HAVE A SCHEME
        new URL(urlString, document.baseURL) // THROW AN EXCEPTION IF THE URL IS TRULY MALFORMED IN SOME WAY
      }
    
      return false
    }
    
    0 讨论(0)
  • 2020-11-29 20:46

    Here's a pretty robust solution for the browser environment:

    Let the browser handle everything. No need for some complicated/error prone regexes.

    const isAbsoluteUrl = (url) => {
      const link = document.createElement('a');
      link.href = url;
      return link.origin + link.pathname + link.search + link.hash === url;
    };
    
    0 讨论(0)
  • 2020-11-29 20:48
    var external = RegExp('^(https?:)?//');
    if(external.test(el)){
        // do something
    }
    

    EDIT:

    With the next regular expression, you can even check if the link goes to the same domain or to an external one:

    var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')');
    if(external.test(el)){
        // do something
    }
    
    0 讨论(0)
  • 2020-11-29 20:48

    Don't use low-level stuff like regexp etc. These things have been solved by so many other people. Especially the edge cases.

    Have a look at URI.js, it should do the job: http://medialize.github.io/URI.js/docs.html#is

    var uri = new URI("http://example.org/");
    uri.is("absolute") === true;
    
    0 讨论(0)
  • 2020-11-29 20:51

    Even more Universal RFC-compliant URI approach:

    (?:^[a-z][a-z0-9+.-]*:|\/\/) regex explanation

    The other solutions listed here would fail for links like mailto:evan@nylas.com

    RFC 3986 defines a Scheme as:

    scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )

    3.1. Scheme https://tools.ietf.org/html/rfc3986#section-3.1

    While the protocol-relative url is technically valid as per section 4.2, Paul Irish has swung back the other way and considers this an anti-pattern. See http://www.paulirish.com/2010/the-protocol-relative-url/

    4.2. Relative Reference http://tools.ietf.org/html/rfc3986#section-4.2

    If you'd like the regex without protocol-relative url's use:

    ^[a-z][a-z0-9+.-]*:

    To see a full list of other types of valid uri edge cases, check out the list here: https://en.wikipedia.org/wiki/URI_scheme

    0 讨论(0)
  • 2020-11-29 20:51

    Nowdays, when a lot of services use protocol-relative URL (eg. //cdn.example.com/libary.js), this method is safer:

    var isAbsolute = new RegExp('^([a-z]+://|//)', 'i');
    
    if (isAbsolute.test(urlString)) {
      // go crazy here
    }
    
    0 讨论(0)
提交回复
热议问题