简体   繁体   中英

Would dynamically created JavaScript files be cached?

So my application uses a LOT of js files. thats a lot of http requests. I decided to combine them dynamically at the server in packs of 3-4 files clubbed by functionality.


My client side request is: ...script type="text/javascript" src="http://mydomain.com/core-js.php" ...

My server side does: --core-js.php-- header("Content-type: application/x-javascript");

include_once('file1.js'); include_once('file2.js'); include_once('file3.js'); include_once('file4.js');


I am setting a far future expire header on core-js.php. My question is, would core-js.php be cached at the client side? If it would be, could someone please explain how?

Thanks!

The client doesn't know or care that what got sent to it was satisfied by bringing together several files server-side. The client should cache it if the caching headers are correct. You'll want to check them carefully to be sure that your PHP install isn't sending other headers that conflict (Firefox+Firebug is good for this), since PHP pages tend to be used for dynamic stuff where you don't want caching.

Please see: http://www.jonasjohn.de/snippets/php/caching.htm , you have to check the incoming request headers to send the right response. You can do something like below:

<?php
ob_start();
$filemtimes = array();
foreach(array('file1.js','file2.js') as $file)
{
include_once($file); 
$filemtimes[]= filemtime($file);
}

$date = gmdate('D, d M Y H:i:s', max($filemtimes)).' GMT';
$length = ob_get_length();
$etag = md5($date.$lengte);

$headers = apache_request_headers();


if(!empty($headers['If-None-Match']) && !empty($headers['If-Modified-Since']))
{

if
(
    $etag == md5($headers['If-Modified-Since'].$length)
)
{

        ob_end_clean();

            header("Content-type: application/x-javascript");
        header('Last-Modified: '.$date."\r\n");
        header('Expires: '.gmdate('D, d M Y H:i:s', (time()+3600)).' GMT'."\r\n");
        header('Cache-Control: max-age=3600'."\r\n");
        header('ETag: '.$headers['If-None-Match']."\r\n");
            header('HTTP/1.1 304 Not Modified');
        header('Connection: close');

        exit;
    }   
}
header("Content-type: application/x-javascript");
header('Last-Modified: '.$date."\r\n");
header('Expires: '.gmdate('D, d M Y H:i:s', (time()+3600)).' GMT'."\r\n");
header('Cache-Control: max-age=3600'."\r\n");
header('ETag: '.$headers['If-None-Match']."\r\n");
header('Content-Length: '.$length."\r\n");
header('Accept-Ranges: bytes'."\r\n");
ob_end_flush();
exit;
?>

Your script will be cached. No data is send to the client. Server side the includes and modification calculation is done for every request. Maybe store etag and modification time in session or cookie to do the check before includes and calculations. Or check filesizes instead of includes.

Yes, but it's complicated. PHP by default adds a bunch of headers which prevent caching. You'll have to make sure you're removing all of them. Also, does your PHP script understand If-Modified-Since and If-None-Match headers? Do you even generate Last-Modified and ETag headers in the first place? This is tricky to get right, and why bother, when your webserver has all that built into it?

I'd do this differently. Make the request to core.js , not core.php . Of course, core.js does not exist, so .htaccess catches the request and directs it to index.php . Now index.php generates the required javascript and serves it to the client. It also creates the file core.js . Future requests for core.js will be handled by Apache as normal for static files, without going near PHP.

And if you want to be able to update the javascript, you can instead use URLs of the form last-modified-timestap.core.js . Changing the timestamp in the HTML will generate a new javascript file on the first request.

I do this for dynamically created CSS (the designer can edit CSS in the administration panel, with values saved into the database), and it works well.

绝大多数浏览器和缓存代理都会尊重到期标头(如果设置)。

Yes it will. The client doesn't know that the js file he's requesting is a bunch of other files chunked into one, he's just seeing one js file, the one he requested and it's telling him to cache it, core-js.php. As long as you don't change the name of the file (core-js.php) there should be no problem.

On another note, you should take a look at Minify http://code.google.com/p/minify/ You can merge and cache not only js but css in groups, basically what you're doing. I've been using it for a while with no problems and it's pretty nice.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM