Wednesday, April 6, 2011

Is it valid to replace http:// with // in a <script src="http://...">?

I have the following tag:

<script type="text/javascript" src="https://cdn.example.com/js_file.js"></script>

In this case the site is HTTPS, but the site may also be just HTTP. (The JS file is on another domain.) I'm wondering if it's valid to do the following for convenience sake:

<script type="text/javascript" src="//cdn.example.com/js_file.js"></script>

I'm wondering if it's valid to remove the http: or https: ?

It seems to work everywhere I have tested, but are there any cases where it doesn't work?

From stackoverflow
  • This will work for both.

    <script type="text/javascript">
    document.write([
        "\<script src='",
        ("https:" == document.location.protocol) ? "https://" : "http://",
        "foo.js' type='text/javascript'>\<\/script>"].join(''));
    </script>
    
    Darryl Hein : I wanted to avoid all the extra code.
    Ned Batchelder : The protocol-less URL that Darryl showed will work for both. There's no need to jump through these hoops.
    Charlie Somerville : why not just use: document.location.protocol + "//foo.bar/script.js" ?
  • A relative URL without a scheme (http: or https:) is valid, per RTF 3986: Section 4.2. If a client chokes on it, then it's the client's fault because they're not complying with the URI syntax specified in the RFC.

    Your example is valid and should work. I've used that relative URL method myself on heavily trafficked sites and have had zero complaints. Also, we test our sites in Firefox, Safari, IE6, IE7 and Opera. These browsers all understand that URL format.

    Chuck : That doesn't appear to be a relative URL in the question. It looks like an absolute URL that's missing the protocol.
    Jeff : It is indeed relative. Take a look at RFC 3986, section 4.
    ng : I agree its relative, // == / relative begins with / absolute does not. So cdn.example.com/js_file.js is absolute but /cdn.example.com/js_file.js or //cdn.example.com/js_file.js is relative.
    Miles : @Jeff: wow, I'd never come across that before. Cool stuff.
    bigmattyh : "If a client chokes on it, then it's the client's fault because they're not complying with the URI syntax specified in the RFC." -- I think this is an interesting question -- but whether a client follows "the spec" is hardly a good standard for whether it's wise to do in a web app.
    Ned Batchelder : Although this technique seems to be little known, it is supported in all the web browsers. It works just great.
    Darryl Hein : I wonder why google doesn't use this for analytics. They use the document.location.protocol method.
    Matchu : When they say relative URL, it means relative as in on the same protocol.
  • If its in another domain, check out the HTTP Referer header. This will contain the referring page. From there take the scheme

    Referer: https://some.other.domain/blah.html
    

    Extract on the server side and add in to the page. However, have to say, I like the document.location.protocol solution proposed.

  • It is perfectly valid to leave off the protocol. The URL spec has been very clear about this for years, and I've yet to find a browser that doesn't understand it. I don't know why this technique isn't better known, it's the perfect solution to the thorny problem of crossing HTTP/HTTPS boundaries. More here: Http-https transitions and relative URLs

  • Many people call this a Protocol Relative URL.

    It causes a double-download of CSS files in IE 7 & 8.

    Andrew Moore : -1: It's actually called a scheme-less URI.
    SLaks : @Andrew: Edited.
    jessegavin : +1 nice side note.
  • Here I duplicate the answer in http://stackoverflow.com/questions/954327/hidden-features-of-html/960111#960111:

    Using a protocol-independent absolute path:

    <img src="//domain.com/img/logo.png"/>
    

    If the browser is viewing an page in SSL through HTTPS, then it'll request that asset with the https protocol, otherwise it'll request it with HTTP.

    This prevents that awful "This Page Contains Both Secure and Non-Secure Items" error message in IE, keeping all your asset requests within the same protocol.

    Caveat: When used on a <link> or @import for a stylesheet, IE7 and IE8 download the file twice. All other uses, however, are just fine.

  • Yes, this is documented in RFC 3986, section 5.2:

    (edit: Oops, my RFC reference was outdated).

  • It is guaranteed to work in any mainstream browser (I'm not taking browsers with less than 0.05% market share into consideration). Heck, it works in Internet Explorer 3.0.

    RFC 3986 defines a URI as composed of the following parts:

         foo://example.com:8042/over/there?name=ferret#nose
         \_/   \______________/\_________/ \_________/ \__/
          |           |            |            |        |
       scheme     authority       path        query   fragment
    

    When defining relative URIs (Section 5.2), you can omit any of those sections, always starting from the left. In pseudo-code, it looks like this:

     result = ""
    
      if defined(scheme) then
         append scheme to result;
         append ":" to result;
      endif;
    
      if defined(authority) then
         append "//" to result;
         append authority to result;
      endif;
    
      append path to result;
    
      if defined(query) then
         append "?" to result;
         append query to result;
      endif;
    
      if defined(fragment) then
         append "#" to result;
         append fragment to result;
      endif;
    
      return result;
    

    The URI you are describing is a scheme-less relative URI.

    Chris : Yeah I guess I thought scheme and authority were always mutually dependent. It makes sense that it's not, but it's not something I've encountered until very recently.
    Roger Pate : It is not guaranteed to work in any browser. It is guaranteed to work only in browsers that follow the RFC.
    Andrew Moore : @Roger Pate: I have yet to see a browser not follow the RFC for URI. That particular standard has been around for so long... I've just tested it in IE3.0 and it understands it perfectly fine. If you fall on a browser that doesn't understand those links, chances are it is such a marginal browser that it won't matter.
    Roger Pate : @Andrew: Maybe you differ from me, but when I say "guarantee" in the context of programming, I really mean "there is no way this can possibly, ever fail," not just "it only works in popular implementations that I've tested." I didn't mean to make a big deal out of it, but it seemed important enough to mention.
    Andrew Moore : @Roger: Yes, but in the context of web development, marginal browsers (<0.01% market share) are not taken into consideration. It's like saying that an API is present in all versions of Windows and then someone comes it to say that it might not be supported in Wine...
    Kugel : strip semicolons and endifs and you get Python , wow :-)
    Roger Pate : @Kugel: Yes, Python is readable. :) -- @Andrew: Marginal browsers like IE7&8? SLaks points out how they have problems using these URLs, which is the type of nuance hidden by "guaranteed to work" in a technical context. All you have to say is "RFC 3986 requires this behavior, which all mainstream browsers handle," but that's already said on the [duplicate](http://stackoverflow.com/questions/550038/) anyway.
    Andrew Moore : @Roger Pate: Loading a CSS file twice doesn't break a site. It's a minor inconvenience that technical users won't notice anyway. And you should know that nothing is guaranteed in IT anyway. There are always edge cases.

0 comments:

Post a Comment