一个php文件实现反代jsdelivr,并缓存文件到本地服务器

一个php文件实现反代jsdelivr,并缓存文件到本地服务器

苏苏
2022-05-16 / 4 评论 / 159 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2022年05月30日,已超过1159天没有更新,若内容或图片失效,请留言反馈。

之前写了shell脚本,可以手动下载jsdelivr的单文件,已经满足的我需求了( ),但评论区表示没有一步到位。

那就用最好的语言之php配合伪静态再搞一个吧!话不多说,直接上代码!

将下面的代码保存为jsd.php

<?php
$file = $_SERVER['REQUEST_URI'];
$self_path = pathinfo($_SERVER['PHP_SELF'], PATHINFO_DIRNAME);
$query = '';
if($_SERVER['QUERY_STRING'])
{
    $file = explode('?', $file)[0];
    $query = '?' . $_SERVER['QUERY_STRING'];
}
# 分离提取需要获取的文件信息
$file_info = pathinfo($file);
$path = $file_info['dirname'];

# 屏蔽异常请求
if($path=='/') exit('/* ??? */');

# 获得文件mimetype,输出必须
$mimetype = get_mimetype($file_info['extension']);

$cdn_file = $file;
# 加这个判断可以兼容根目录
if(strlen($self_path)>1){
   $cdn_file = substr($file, strlen($self_path));  
}

# 本地目录不存在则创建
$local_path = substr(pathinfo( $cdn_file, PATHINFO_DIRNAME), 1);
if($local_path && !is_dir($local_path)){
    @mkdir($local_path, 755, true);
}

$url = 'https://cdn.jsdelivr.net' . $cdn_file . $query;

# 获取数据并保存、输出
$content = curl($url);
if($content){
    header('content-type:'. $mimetype .';charset=utf-8');
    echo '/* ' . $url .'*/';
    file_put_contents(substr($cdn_file, 1), $content);
    exit($content);
}else{
    header('location: ' .$url );
}

/**
 * curl封装
 * @param string $url
 * @return string
 */
function curl($url)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 3000);
    curl_setopt($ch, CURLOPT_TIMEOUT_MS, 3000);
    if (strpos($url, 'https') !== false) {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    }
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36');
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}
/**
 * 根据文件后缀获取其mine类型
 * @param string $extension
 * @return string
 */
 function get_mimetype($extension) {
    $ct['htm'] = 'text/html';
    $ct['html'] = 'text/html';
    $ct['txt'] = 'text/plain';
    $ct['asc'] = 'text/plain';
    $ct['bmp'] = 'image/bmp';
    $ct['gif'] = 'image/gif';
    $ct['jpeg'] = 'image/jpeg';
    $ct['jpg'] = 'image/jpeg';
    $ct['jpe'] = 'image/jpeg';
    $ct['png'] = 'image/png';
    $ct['ico'] = 'image/vnd.microsoft.icon';
    $ct['mpeg'] = 'video/mpeg';
    $ct['mpg'] = 'video/mpeg';
    $ct['mpe'] = 'video/mpeg';
    $ct['qt'] = 'video/quicktime';
    $ct['mov'] = 'video/quicktime';
    $ct['avi'] = 'video/x-msvideo';
    $ct['wmv'] = 'video/x-ms-wmv';
    $ct['mp2'] = 'audio/mpeg';
    $ct['mp3'] = 'audio/mpeg';
    $ct['rm'] = 'audio/x-pn-realaudio';
    $ct['ram'] = 'audio/x-pn-realaudio';
    $ct['rpm'] = 'audio/x-pn-realaudio-plugin';
    $ct['ra'] = 'audio/x-realaudio';
    $ct['wav'] = 'audio/x-wav';
    $ct['css'] = 'text/css';
    $ct['zip'] = 'application/zip';
    $ct['pdf'] = 'application/pdf';
    $ct['doc'] = 'application/msword';
    $ct['bin'] = 'application/octet-stream';
    $ct['exe'] = 'application/octet-stream';
    $ct['class'] = 'application/octet-stream';
    $ct['dll'] = 'application/octet-stream';
    $ct['xls'] = 'application/vnd.ms-excel';
    $ct['ppt'] = 'application/vnd.ms-powerpoint';
    $ct['wbxml'] = 'application/vnd.wap.wbxml';
    $ct['wmlc'] = 'application/vnd.wap.wmlc';
    $ct['wmlsc'] = 'application/vnd.wap.wmlscriptc';
    $ct['dvi'] = 'application/x-dvi';
    $ct['spl'] = 'application/x-futuresplash';
    $ct['gtar'] = 'application/x-gtar';
    $ct['gzip'] = 'application/x-gzip';
    $ct['js'] = 'application/javascript';
    $ct['swf'] = 'application/x-shockwave-flash';
    $ct['tar'] = 'application/x-tar';
    $ct['7z'] = 'application/x7zcompressed';
    $ct['rar'] = 'application/x-rar-compressed';
    $ct['xhtml'] = 'application/xhtml+xml';
    $ct['au'] = 'audio/basic';
    $ct['snd'] = 'audio/basic';
    $ct['midi'] = 'audio/midi';
    $ct['mid'] = 'audio/midi';
    $ct['m3u'] = 'audio/x-mpegurl';
    $ct['tiff'] = 'image/tiff';
    $ct['tif'] = 'image/tiff';
    $ct['rtf'] = 'text/rtf';
    $ct['wml'] = 'text/vnd.wap.wml';
    $ct['wmls'] = 'text/vnd.wap.wmlscript';
    $ct['xsl'] = 'text/xml';
    $ct['xml'] = 'text/xml';
    
    return isset($ct[strtolower($extension)]) ? $ct[strtolower($extension)] : 'text/html';
}

伪静态规则

  • 如果你的服务器是Apache,可以在jsd.php文件所在的文件夹新建一个.htaccess文件,内容如下
# Apache
<IfModule mod_rewrite.c>
    RewriteEngine on
    # 这里的/记得修改为jsd.php所在的实际绝对路径
    RewriteBase /
 
    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule .* jsd.php [QSA,L]
    
</IfModule>
  • 如果服务器是Nginx,因为我不用,不知道怎么写,自己看着编吧

用法介绍

  • 如果放在根目录,直接把cdn.jsdelivr.net替换成你的域名就好了
  • 如果放在某个子目录下,比如cdn目录下,把cdn.jsdelivr.net替换成你的域名/cdn(如https://example.com/cdn)即可
同步发布: https://cloud.tencent.com/developer/article/2003871
1

评论 (4)

取消
  1. 头像
    vian
    Windows 10 · Google Chrome
    @

    刚好我用的nginx 我也不会表情

    回复
  2. 头像
    晨曦
    Android · Google Chrome
    @

    有一个爬全部的就好了 我自己做个定时访问全部个自己缓存下来

    回复
  3. 头像
    ssdsl
    Windows 10 · MicroSoft Edge
    @

    这个无法把整个目录扒下来,只能把绝对路径的文件自动下载
    比如需要加载https://cdn.jsdelivr.net/npm/jquery@1.11.3

    回复
    1. 头像
      苏苏 作者
      Windows 10 · MicroSoft Edge
      @ ssdsl

      本文目的是按需下载,而不是爬取目录表情

      回复