views:

829

answers:

8

I have the following tag:

<script type="text/javascript" src="https://cdn.example.com/js_file.js"&gt;&lt;/script&gt;

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?

+1  A: 

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>
Mark Hurd
I wanted to avoid all the extra code.
Darryl Hein
The protocol-less URL that Darryl showed will work for both. There's no need to jump through these hoops.
Ned Batchelder
why not just use: document.location.protocol + "//foo.bar/script.js" ?
Charlie Somerville
+14  A: 

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.

Jeff
That doesn't appear to be a relative URL in the question. It looks like an absolute URL that's missing the protocol.
Chuck
It is indeed relative. Take a look at RFC 3986, section 4.
Jeff
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.
ng
@Jeff: wow, I'd never come across that before. Cool stuff.
Miles
"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.
bigmattyh
Although this technique seems to be little known, it is supported in all the web browsers. It works just great.
Ned Batchelder
I wonder why google doesn't use this for analytics. They use the document.location.protocol method.
Darryl Hein
When they say relative URL, it means relative as in on the same protocol.
Matchu
A: 

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.

ng
+7  A: 

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

Ned Batchelder
+4  A: 

Many people call this a Protocol Relative URL.

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

SLaks
-1: It's actually called a scheme-less URI.
Andrew Moore
@Andrew: Edited.
SLaks
+1 nice side note.
jessegavin
+3  A: 

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.

KennyTM
+2  A: 

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

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

gnud
+9  A: 

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.

Andrew Moore
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.
Chris
It is not guaranteed to work in any browser. It is guaranteed to work only in browsers that follow the RFC.
Roger Pate
@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.
Andrew Moore
@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.
Roger Pate
@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...
Andrew Moore
strip semicolons and endifs and you get Python , wow :-)
Kugel
Roger Pate
@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.
Andrew Moore