Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I specify the protocol in an anchor and still use relative path?

It is always preferred on a personal website to use relative paths in anchors so that you can easily move your directory structure to a new website, but I want to make part of my website password protected (using .htaccess) and hence use https. Is there a way in an anchor's href to specify a different protocol without hard-coding the www.domain.com as well?

Example:

<a href="/student/example">Link</a>

I want to turn it into something like:

<a href="https: /student/example">Link</a>

The above obviously doesn't work. Is there any way to do it? I am trying to avoid any scripting but would appreciate a JavaScript more than PHP or ASP.

like image 884
Kevin_Ankiewicz Avatar asked Jun 11 '13 23:06

Kevin_Ankiewicz


People also ask

What is protocol relative URL?

A protocol-relative URL (PRURL) is the method for linking to a website that offers both HTTP and HTTPS, while HTTPS links should be used for HTTPS-only websites and HTTP links should be used for sites that don't support HTTPS at all.

How do you write a relative URL?

To link pages using relative URL in HTML, use the <a> tag with href attribute. Relative URL is used to add a link to a page on the website. For example, /contact, /about_team, etc.

Can URI be relative?

A relative URI is a URI that doesn't provide the protocol used to access the resource nor the name of the computer hosting it, and therefore can only be used to refer to another document in the same computer.

Do you have to include HTTPS in links?

Answer. Links are recommended to be inserted with the https or http protocol. Certain URLs, for example subdomain1.subdomain2.domain.com are saved as a relative path, if the protocol was not added. Adding the https or http protocol prevents links from being as relative paths, or anchor links in the body of the article.


2 Answers

You can't do this without relying on Javascript to dynamically change the href. The way the relative URIs are transformed into absolute URIs is described in RFC 3986 Section 5.2.2:

if defined(R.scheme) then
   T.scheme    = R.scheme;
   T.authority = R.authority;
   T.path      = remove_dot_segments(R.path);
   T.query     = R.query;
else
   if defined(R.authority) then
      T.authority = R.authority;
      T.path      = remove_dot_segments(R.path);
      T.query     = R.query;
   else
      if (R.path == "") then
         T.path = Base.path;
         if defined(R.query) then
            T.query = R.query;
         else
            T.query = Base.query;
         endif;
      else
         if (R.path starts-with "/") then
            T.path = remove_dot_segments(R.path);
         else
            T.path = merge(Base.path, R.path);
            T.path = remove_dot_segments(T.path);
         endif;
         T.query = R.query;
      endif;
      T.authority = Base.authority;
    endif;
    T.scheme = Base.scheme;
  endif;
  T.fragment = R.fragment;

Where R is the relative URL and T is the target.

The above basically says that if the scheme is specified in the relative URI, then the target uri will be the entire relative uri, so the only way to specify the scheme is to specify the entire url.

If you want to go with a Javascript based approach you can dynamically set the href using something like: a.href = 'https://' + window.location.host + a.getAttribute('href'). Where a is your AnchorElement.

Here is a demo of the Javascript version: http://jsfiddle.net/7DWV5/

However, largely for the reason you've encountered, it is a good idea to either store your hostname in a config file, or detect it from the HTTP Request Host header in a front controller. That way you can just template it in to your HTML while generating the page. That saves you from having to use client-side scripts to fix your urls after they've been generated, which may be desirable, because not everyone has Javascript enabled.

like image 200
Paul Avatar answered Nov 09 '22 04:11

Paul


I think that there is no "simple" solution... And javascript seems to be a bad idea for such purposes.

You could try:

<base href="https://yourdomain.com/">

placed in document header.

OR

yours idea:

<a href="/test-me1/">regular link 1</a>
<a href="/test-me2/">regular link 2</a>
<a href="/https/test-me3/">secure link</a>

and in the bottom, but before closing body tag place something like this:

<script type="text/javascript">
(function(){

    var h = 'yourdomain.com';
    /* could be replaced with something like window.location.host */

    var a =  document.links;

    for (var c = 0; c < a.length; c++) {

        var i = a[c].href.indexOf('/https/');

        if(-1 !== i)
        {
            a[c].href = 'https://' + h + '/' + a[c].href.substring( i + 7 );
            /* where 7 is a length of '/https/' */
        }
    }
})();
</script>

OR even simply:

<script type="text/javascript">
(function(){

    var a = document.links;

    for (var c = 0; c < a.length; c++) {

        if(-1 !== a[c].href.indexOf('/https/') )
        {
            a[c].href = a[c].href.replace('/https/','').replace('http:','https:');
        }
    }
})();
</script>
like image 40
Chris Avatar answered Nov 09 '22 03:11

Chris