21

When I´m in a secure part of a web-site I´m developing (entering a specific page or folder using https), the relative links to the normal pages are automatically converted to https as well.

Is there a way to tell an <a> tag to always use the http protocol instead of the https protocol (or the other way around)?

I know it´s easy using the complete link (http://www.mysite.com/index.html or https://www.mysite.com/index.html), but I would like it to work with relative links (index.html, ../index.html, etc.).

jeroen
  • 91,079
  • 21
  • 114
  • 132

6 Answers6

30

You can make all your internal links be protocol independent by using the following syntax:

<a href="//some/file/on/your/domain.php">link text</a>

instead of

<a href="some/file/on/your/domain.php">link text</a>

the // will make the link respect whatever protocol the page was loaded over.

Matt
  • 9,068
  • 12
  • 64
  • 84
  • 1
    Thanks for your answer. I haven´t tried it, but normal, relative links always follow the protocol that the originating page was loaded over, so this would not change anything. Apart from that I want specific - relative - pages and directories to load over https and others over http. – jeroen Feb 07 '10 at 18:29
  • Sorry, I misread your question. I've just gone back and read it and it really doesn't apply. – Matt Feb 07 '10 at 21:26
  • 5
    Starting a URI with two slashes is a "network-path reference" and works as Matt described **as long as you specify a domain**. You can't use this syntax for local files as the example seems to indicate (the browser would try to resolve "some" as if it were a domain). See [URI starting with two slashes … how do they behave?](http://stackoverflow.com/questions/4071117/uri-starting-with-two-slashes-how-do-they-behave) – Rudi Mar 28 '11 at 16:13
  • @Rudi, The example is now updated to cover this. My use of the word "local" was ambiguous. I meant it in the sense that it was on the same domain, rather than being on a local machine. – Matt Dec 11 '13 at 14:30
  • @Matthew please edit your answer considering Rudi's comment. – tzot Nov 21 '17 at 11:41
10

We use Apache mod_rewrite to control whether a page is served via http or https. Here's an example snippet from a site's root directory .htaccess file:

# Redirect most reqests for https to http
RewriteRule ^https://www.example.com(.*) http://www.example.com$1 [R=301,NC]

# Allow some URIs to be https if requested
RewriteCond   %{SERVER_PORT}  ^443$
RewriteCond   %{REQUEST_URI}  !^/images/(.*)$
RewriteCond   %{REQUEST_URI}  !^/scripts/(.*)$
RewriteCond   %{REQUEST_URI}  !^/styles/(.*)$
RewriteCond   %{REQUEST_URI}  !^/store(.*)$
RewriteCond   %{REQUEST_URI}  !^/login.htm$
RewriteRule ^(.*) http://www.example.com/$1 [L,R]

# Force some URIs to be https only
RewriteCond   %{SERVER_PORT}  ^80$
RewriteRule ^store(.*) https://www.example.com/store$1 [L,R]

RewriteCond   %{SERVER_PORT}  ^80$
RewriteRule ^FormSanityKey.htm https://www.example.com/login$1 [L,R]

Read all about it at:

http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html

Jans Carton
  • 196
  • 3
4

Not sure if this is exactly what you were looking for, but if you're using Apache, there's a trick you can use to do this: http://httpd.apache.org/docs/2.2/ssl/ssl_faq.html#relative

Basically you put the following in your Apache configuration file:

RewriteEngine on
RewriteRule ^/(.*):SSL$ https://%{SERVER_NAME}/$1 [R,L]
RewriteRule ^/(.*):NOSSL$ http://%{SERVER_NAME}/$1 [R,L]

then append :SSL to any link (in the webpage) for which you want to force HTTPS, and :NOSSL to any link for which you want to force regular HTTP.

David Z
  • 128,184
  • 27
  • 255
  • 279
3

It sounds like you want to use the BASE element.

There is no way to 'tell' an Anchor to use a specific protocol or not, at least without using the BASE element in the HEAD of that page.

Is there a reason why you want to use relative links over absolute links? This article talks about the pitfall of using relative links with HTTPS - the potential to have your site double indexed and such.

Nick Presta
  • 28,134
  • 6
  • 57
  • 76
  • 2
    Thanks. The base element would affect all links on the page and there will be both kinds on the same page (http and https). I also prefer relative links because it makes life (testing, etc...) on an slow internet connection a lot easier and I can test sites in folders on the server. – jeroen Feb 25 '09 at 01:11
  • 1
    Double indexing of your site? Isn't it a problem of the indexing machine? Like - don't they check the files for identical content? I don't support coining "rules" for webmasters based on how wrong do search engines work at a particular point in time (which may be different from their future behavior anyway). – Tomasz Gandor Nov 27 '14 at 05:54
2

There is no way to do this with relative hyperlinks as your are using a different protocol, it would be no different than linking to a ftp location.

Damien McGivern
  • 3,954
  • 3
  • 27
  • 21
  • 2
    It's just a shortcomming of the URL/URI syntax. I can easily imagine a world where you can have a link with relative path, but absolute protocol (as in "keep the rest, change path and protocol"), just as we do have protocol relative links ("keep protocol, change everything that comes after"). We just happen not to live in this world. – Tomasz Gandor Nov 27 '14 at 05:51
0

I use this code to create a link of the current index page to direct to the https server, because we provide different content according the protocol and we do not know where is hosting.

  <a>Secure server
    <script>
      let url = new URL(window.location);
      url.protocol = 'https:';
      url.port = '443';
      document.currentScript.parentElement.href = url.toString();
    </script>
  </a>
Daniel De León
  • 13,196
  • 5
  • 87
  • 72