From 141dcedd305d74906268e2d5216c54627b46ead9 Mon Sep 17 00:00:00 2001 From: filesite Date: Sat, 5 Oct 2024 13:45:09 +0800 Subject: [PATCH] add etag for smallimg and dirsnap --- conf/app.php | 15 +++++--- controller/Controller.php | 11 +++++- themes/beauty/controller/SiteController.php | 39 +++++++++++++++------ www/js/beauty.js | 2 +- 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/conf/app.php b/conf/app.php index bb99bc1..99bf05f 100644 --- a/conf/app.php +++ b/conf/app.php @@ -3,8 +3,8 @@ * Config */ $configs = array( - 'version' => '0.3.3', - 'releaseDate' => '2024-9-30', + 'version' => '0.3.4', + 'releaseDate' => '2024-10-05', 'showVersion' => false, //默认不显示版本号和发布日期 'default_timezone' => 'Asia/Hong_Kong', //timezone, check more: https://www.php.net/manual/en/timezones.asia.php @@ -56,9 +56,14 @@ $configs = array( 'supportedVideoExts' => array('mp4', 'mov', 'm3u8'), 'supportedAudioExts' => array('mp3'), - 'screenshot_start' => 1000, //视频播放页快照截取开始时间,单位:毫秒 - 'screenshot_expire_seconds' => 315360000, //视频封面图缓存3650天 - 'small_image_zoom_rate' => 2.5, //浏览器生成缩略图在其展示尺寸的放大倍数,以确保清晰度 + 'screenshot_start' => 1000, //视频播放页快照截取开始时间,单位:毫秒 + 'screenshot_expire_seconds' => 315360000, //视频封面图在服务器端缓存时长,单位:秒 + 'small_image_zoom_rate' => 2.5, //浏览器生成缩略图在其展示尺寸的放大倍数,以确保清晰度 + + //缩略图在浏览器端缓存时长,单位:秒 + 'small_image_client_cache_seconds' => 600, + //目录封面图在浏览器端缓存时长,单位:秒 + 'dir_snapshot_client_cache_seconds' => 300, //列表页缩略图尺寸设置 'small_image_min_width' => 360, //缩略图最小宽度设置,以确保清晰度 diff --git a/controller/Controller.php b/controller/Controller.php index 3d0aca2..17751c7 100644 --- a/controller/Controller.php +++ b/controller/Controller.php @@ -89,7 +89,7 @@ Class Controller { } //render json data - protected function renderJson($data, $httpStatus = 200) { + protected function renderJson($data, $httpStatus = 200, $headers = array()) { if (!empty(FSC::$app['config']['debug'])) { $end_time = microtime(true); $data['page_time_cost'] = ceil( ($end_time - FSC::$app['start_time']) * 1000 ); //ms @@ -99,6 +99,9 @@ Class Controller { if ($httpStatus != 200 && is_numeric($httpStatus)) { $title = "HTTP/1.0 {$httpStatus} Internal Server Error"; switch($httpStatus) { + case 304: + $title = "HTTP/1.0 {$httpStatus} Not Modified"; + break; case 401: $title = "HTTP/1.0 {$httpStatus} 未授权"; break; @@ -119,6 +122,12 @@ Class Controller { header($title, true, $httpStatus); } + if (!empty($headers)) { + foreach($headers as $item) { + header($item); + } + } + echo json_encode($data); exit; } diff --git a/themes/beauty/controller/SiteController.php b/themes/beauty/controller/SiteController.php index b623a2e..06ff718 100644 --- a/themes/beauty/controller/SiteController.php +++ b/themes/beauty/controller/SiteController.php @@ -320,8 +320,11 @@ Class SiteController extends Controller { $img_id = ''; $size = 'orignal'; - $cacheId = $this->post('cid', ''); - $cateId = $this->post('id', ''); + $cacheId = $this->get('cid', ''); + $cateId = $this->get('id', ''); + $customHeaders = array(); + $httpStatus = 200; + if (empty($cacheId) || empty($cateId)) { $code = 0; $msg = '参数不能为空'; @@ -388,10 +391,6 @@ Class SiteController extends Controller { $firstVideo = $scanner->getSnapshotImage($realpath, $audioExts); if (!empty($firstVideo)) { $url = '/img/beauty/audio_icon.jpeg'; - - //TODO: 获取音乐封面图 - //$size = 'am'; //音乐封面图 - } } }else { @@ -445,10 +444,21 @@ Class SiteController extends Controller { } }else { $url = $cachedData['url']; + $etag = md5($url); + $etag_from_client = !empty($_SERVER['HTTP_IF_NONE_MATCH']) ? $_SERVER['HTTP_IF_NONE_MATCH'] : ''; //get etag from client + if (!empty($etag) && $etag == $etag_from_client) { + $httpStatus = 304; + } + + $dir_snapshot_client_cache_seconds = FSC::$app['config']['dir_snapshot_client_cache_seconds']; + $customHeaders = array( + "Cache-Control: max-age={$dir_snapshot_client_cache_seconds}", + "Etag: {$etag}", + ); } } - return $this->renderJson(compact('code', 'msg', 'url')); + return $this->renderJson(compact('code', 'msg', 'url'), $httpStatus, $customHeaders); } //保存目录封面图到缓存 @@ -588,6 +598,8 @@ Class SiteController extends Controller { $cacheSubDir = 'image'; $cachedData = Common::getCacheFromFile($cacheKey, $expireSeconds, $cacheSubDir); + $small_image_client_cache_seconds = FSC::$app['config']['small_image_client_cache_seconds']; + //无缓存,则实时生成缩略图 if (empty($cachedData)) { $tmpUrl = parse_url($imgUrl); @@ -602,7 +614,7 @@ Class SiteController extends Controller { //返回图片数据 header("Content-Type: image/jpeg"); - header('Cache-Control: max-age=3600'); //缓存 1 小时 + header("Cache-Control: max-age={$small_image_client_cache_seconds}"); header("Etag: " . md5($img_data)); echo $img_data; exit; @@ -612,9 +624,16 @@ Class SiteController extends Controller { $base64_img = preg_replace('/^data:image\/.+;base64,/i', '', $cachedData); $img_data = base64_decode($base64_img); + + $etag = md5($img_data); + $etag_from_client = !empty($_SERVER['HTTP_IF_NONE_MATCH']) ? $_SERVER['HTTP_IF_NONE_MATCH'] : ''; //get etag from client + if (!empty($etag) && $etag == $etag_from_client) { + header("HTTP/1.0 304 Not Modified", true, 304); + } + header("Content-Type: {$imgType}"); - header('Cache-Control: max-age=3600'); //缓存 1 小时 - header("Etag: " . md5($img_data)); + header("Cache-Control: max-age={$small_image_client_cache_seconds}"); + header("Etag: {$etag}"); echo $img_data; exit; } diff --git a/www/js/beauty.js b/www/js/beauty.js index 45a426e..8161156 100644 --- a/www/js/beauty.js +++ b/www/js/beauty.js @@ -372,7 +372,7 @@ $('.dir_item').each(function(index, el) { if ($(el).find('.im_img').length == 0) { $.ajax({ url: '/site/dirsnap', - method: 'POST', + method: 'GET', dataType: 'json', data: { cid: cid,