PHP实现Github头像缓存
在开发博客Github登录
功能,缓存Github头像
的时候,发现下载头像是个很费劲的事情。
利用位于HK的PHP虚拟主机,可以轻松解决这个问题。
伪静态依赖Apache的Rewrite模块。
PHP代码
// 屏蔽所有报错,避免图片加载失败
error_reporting(0);
// 设置需要返回的头名称
$proxied_headers = array('Set-Cookie', 'Content-Type', 'Cookie', 'Location');
// 获取URL路径
$proxy_request_url = $_SERVER['REQUEST_URI'];
// 设置请求地址HOST
$github_res_host = 'githubusercontent.com';
// 设置当前PHP文件所在相对路径,根目录设置为"/"
$proxy_base_url = '/avatar';
// 如果包含 /index.php 路径
if (strpos($proxy_request_url, $proxy_base_url . '/index.php') === 0) {
// 兼容非伪静态模式
$proxy_request_url = ltrim(substr($proxy_request_url, strlen($proxy_base_url . '/index.php')), '/');
} else {
// 依赖Apache的Rewrite模块
$proxy_request_url = ltrim(substr($proxy_request_url, strlen($proxy_base_url)), '/');
}
// 判断请求地址是否符合$github_res_host规定,防止滥用
if (strpos(substr($proxy_request_url, 0, strpos($proxy_request_url, '/')), $github_res_host) === false) {
die("403");
}
// 最终请求的远程地址
$proxy_request_url = "https://" . $proxy_request_url;
// 初始化 CURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $proxy_request_url);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
// 设置请求的 Cookie,此处用不到
// if (isset($_SERVER['HTTP_COOKIE'])) {
// $client_headers[] = "Cookie: " . $_SERVER['HTTP_COOKIE'];
// }
// 设置请求的 User-Agent
if (isset($_SERVER['HTTP_USER_AGENT'])) {
$client_headers[] = "User-Agent: " . $_SERVER['HTTP_USER_AGENT'];
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $client_headers);
$res = curl_exec($ch);
curl_close($ch);
// 解析请求到的结果
list($headers, $body) = explode("\r\n\r\n", $res, 2);
$headers = explode("\r\n", $headers);
$hs = array();
foreach ($headers as $header) {
if (false !== strpos($header, ':')) {
list($h, $v) = explode(':', $header);
$hs[$h][] = $v;
} else {
$header1 = $header;
}
}
// 设置返回头
list($proto, $code, $text) = explode(' ', $header1);
header($_SERVER['SERVER_PROTOCOL'] . ' ' . $code . ' ' . $text);
foreach ($proxied_headers as $header_name) {
if (isset($hs[$header_name])) {
foreach ($hs[$header_name] as $v) {
if ($header_name !== 'Set-Cookie') {
header($header_name . ": " . $v, false);
} else {
header($header_name . ": " . $v);
}
}
}
}
die($body);
伪静态配置
Apache伪静态配置文件.htaccess
RewriteEngine on
RewriteBase /avatar
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php)
RewriteRule ^(.*)$ index.php?/$1 [L]
开启伪静态前:https://域名/avatar/index.php/avatars2.githubusercontent.com/u/6657330?v=4
开启伪静态后:https://域名/avatar/avatars2.githubusercontent.com/u/6657330?v=4
。
测试地址:https://apio.xyz/avatar/avatars2.githubusercontent.com/u/6657330?v=4
JavaScript使用示例
const avatorDownloadURL = 'https://apio.xyz/avatar/' + avatarURL.replace('https://', '')
如此,GitHub OAuth 第三方登录
缓存头像时便可快速下载。
为什么不直接使用URL参数?
通过拼接路径并直接返回图片Header头(Content-Type
是对应图片的格式)的方式,方便直接在前端<img>
标签中引用图片,浏览器兼容性更好。实际使用时建议同步下载图片后上传到对象存储。
除特别注明外,本站所有文章均为原创。原创文章均已备案且受著作权保护,未经作者书面授权,请勿转载。
打赏
交流区(6)
666
2020年7月23日 06:50回复
😄
2020年7月23日 06:51回复
有意思
2020年7月23日 09:45回复
可以🉑
2020年7月23日 09:49回复
666
2020年7月23日 09:53回复
赶紧给你博客也加上登录!!😂
2020年7月23日 09:54回复
老师你好,我希望能用一个openwrt路由器实现IPv4和IPv6的桥接,请问我该如何实现?我尝试了直接新增dhcpv6的接口,但是效果不甚理想(无法成功获取公网的ipv6,但是直连上级路由的其他设备是可以获取公网的ipv6地)
![%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE20241205230845.png](https://cdn.wyr.me/visitor-files/2024-12-05/1733411344287屏幕截图 2024-12-05 230845.png)你好
,为什么我这里是0039 813C 0600 0075 16xx xx xx,只有前6组是相同的,博客中要前8位相同,这个不同能不能照着修改呢?我系统版本是Win1124H2
大神你好,win11专业版24h2最新版26100.2033,文件如何修改?谢谢
win11专业版24h2最新版26100.2033,Windows Feature Experience Pack 1000.26100.23.0。C:\Windows\System32\termsrv.dll系统自带的这个文件,39 81 3C 06 00 00 0F 85 XX XX XX XX 替换为 B8 00 01 00 00 89 81 38 06 00 00 90。仍然无法远程连接。原来是win11 21h2系统,是可以远程链接的。共享1个主机,2个显示器,2套键鼠,各自独立操作 各自不同的账号,不同的桌面环境。
博主,win11专业版24h2最新版,C:\Windows\System32\termsrv.dll系统自带的这个文件,找不到应该修改哪个字段。我的微信:一三五73二五九五00,谢谢