PHP: How to add expire headers for external scripts

PHP: How to add expire headers for external scripts

Every website is using external JavaScript files. They are required for example when using Google Analytics, or an ad provider like BuySellAds. In order to leverage browser caching and optimize your website speed, it is recommended that you add expire headers to your script, which you can't do on external files. In this article, I'll show you how to dynamically import external JavaScript files into your own website for better performance.


The problem with external scripts

When using an external service as such as Google Analytics, you are often required to include external JavaScript files into your own website.

While this isn’t a problem per se, you obviously don’t have as much control over those files than over files hosted on your own server. This is especially problematic since you should always set an expire header to static files in order to leverage browser caching and optimize your website speed.

Google PageSpeed Insight will recommend you to do so:

The solution: Adding expire headers to external scripts

So what we need to do is to import all the .js files dynamically into our website. To do so, we’ll use PHP and the file_get_contents() function.

The first thing to do is to locate the external script:

<script type="text/javascript" src="https://ssl.google-analytics.com/ga.js"></script>

The next step is to create a .php file. Let’s call it externaljs.php. Insert the following code in it:

<?php

$files = array(
	'ga.js' => 'https://ssl.google-analytics.com/ga.js',
	'bsa.js' => 'https://s3.buysellads.com/ac/bsa.js',
	'pro.js' => 'https://s3.buysellads.com/ac/pro.js'
);

if(isset($files[$_GET['file']])) {
	if ($files[$_GET['file']] == 'ga.js'){
		header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time() + ((60 * 60) * 48))); // 2 days for GA
	} else {
		header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time() + (60 * 60))); // Default set to 1 hour
	}

	echo file_get_contents($files[$_GET['file']]);
}

?>

Let’s have a look at the code:

  • Lines 3 to 7: An array containing the accepted files is created. This is super important since otherwise any file could be embedded into your site, leading to potential security problems.
  • Lines 9 to 14: Since we need to adjust the expiring time for every script, we need a conditional statement to do so.
  • Line 16: If the script passed out as a GET parameter is found in our array, we can now safely display it.

You’ll need to adjust the code and enter the URLs of your external scripts. Once done, just upload it onto your server. If you’re using WordPress, it’s a good idea to put the file in your theme folder.

Then, simply replace the external .js call and replace it by a call to your externaljs.php file, as shown below:

<script type="text/javascript" src="externaljs.php?file=ga.js"></script>

And you’re done. You can now dynamically import external .js file on your server and therefore, set the right expire header for each script.

Enjoyed this article? Please consider donating: 3FVR5qaxYV8yAgNUUS7FC3o8c54YfDR5zK
  • Ivo Bathke

    this is not a good idea security wise:
    dont use $_GET[‘file’] so everyone can open any file on your page. imagine externaljs.php?url=config.inc.php

    • The code has the $files array which specifies which files can be included. Hence, externaljs.php?url=config.inc.php won’t return anything.

      • Ivo Bathke

        yes correct, so its fine 🙂

        • No problem, when it comes to security, better be TOO careful than not enough 😉

  • Jan-Christoph Ihrens

    So now the browser might be able to take the scripts from the cache more often, but the server has to download the scripts in every case before sending any output. Even taking into account the possibly better bandwidth of the server, I don’t think this will really speed up things; it just makes the PageSpeed results look better. Did you benchmark your solution?

    Apart from that, users of NoScript and similar browser extensions won’t be able to block scripts from certain sources anymore since they are now all delivered by your server. It’s a good idea to self-host scripts you trust, but these come directly from the suppliers and are delivered without any checks. I’m not sure it that’s a good idea.

  • Leopoldo Raul Ocampo Rodriguez

    i get pageblank, just copy and paste your code and trial with ?url=ga.js prefix

    • Jesus

      Same here, blank page. Where does the “url=” come into play?

      • Should read

        Corrected the mistake.

        • Leopoldo Raul Ocampo Rodriguez

          thank you 🙂