WordPress – How to serve resources without http or https (protocol relative url)

By default WordPress will use a full absolute URL for resources such as images, scripts and style sheets.

If the resource is loaded correctly WordPress will automatically use the scheme that your website is configured for (http or https) – however there are situations where your website might switch between using http or https – for example if you were migrating between scripts or you only use https on a limited number of pages.

In these situations you can take advantage of a neat trick many people aren’t aware of – the protocol relative url.

With protocol relative url’s you simple leave off the http: or https: part of the resource path. The browser will automatically load the resource using the same protocol that the page was loaded with.

For example, an absolute url may look like

http://domainname.com/folder/script.js

If you were to load this from a https page the script will not be loaded – as non-https resources are not loaded from https pages (for security reasons).

The protocol relative url would look like

//domainname.com/folder/script.js

and would load if the web page was http or https.

The script below will make WordPress automatically display all your resources (images, scripts, style sheets) from a protocol relative url.

To install I suggest you create a custom plugin, add the script to the custom plugin and enable the plugin. For instructions on how to do this see How to create a WordPress plugin for your custom functions.

function itsg_buffer_wrapup($buffer) {
    // Check for a Content-Type header. Currently only apply rewriting to "text/html" or undefined
    $headers = headers_list();
    $content_type = null;

    foreach ($headers as $header) {
        if (strpos(strtolower($header), 'content-type:') === 0) {
            $pieces = explode(':', strtolower($header));
            $content_type = trim($pieces[1]);
            break;
        }
    }

    if (is_null($content_type) || substr($content_type, 0, 9) === 'text/html') {
        // replace href or src attributes within script, link, base, and img tags with just "//" for protocol
        $re     = "/(<(script|link|base|img|form)([^>]*)(href|src|action)=[\"'])https?:\\/\\//i";
        $subst  = "$1//";
        $return = preg_replace($re, $subst, $buffer);

        // on regex error, skip overwriting buffer
        if ($return) {
            $buffer = $return;
        }
    }
    return $buffer;
}

function itsg_buffer_init() {
    ob_start('itsg_buffer_wrapup');
}

add_action('plugins_loaded', 'itsg_buffer_init');