惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
GRAHAM CLULEY
博客园_首页
博客园 - Franky
Engineering at Meta
Engineering at Meta
雷峰网
雷峰网
The GitHub Blog
The GitHub Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
C
Cisco Blogs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
MyScale Blog
MyScale Blog
Apple Machine Learning Research
Apple Machine Learning Research
宝玉的分享
宝玉的分享
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
F
Full Disclosure
Cloudbric
Cloudbric
J
Java Code Geeks
C
Cybersecurity and Infrastructure Security Agency CISA
Last Week in AI
Last Week in AI
The Hacker News
The Hacker News
量子位
T
The Blog of Author Tim Ferriss
T
Threatpost
Cisco Talos Blog
Cisco Talos Blog
C
Check Point Blog
AWS News Blog
AWS News Blog
Blog — PlanetScale
Blog — PlanetScale
T
Threat Research - Cisco Blogs
Project Zero
Project Zero
Scott Helme
Scott Helme
N
Netflix TechBlog - Medium
A
About on SuperTechFans
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Tenable Blog
S
Schneier on Security
T
Tor Project blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Hacker News: Ask HN
Hacker News: Ask HN
MongoDB | Blog
MongoDB | Blog
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
H
Heimdal Security Blog
T
Tailwind CSS Blog
P
Privacy International News Feed
爱范儿
爱范儿
Google DeepMind News
Google DeepMind News
D
DataBreaches.Net
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园 - 叶小钗
人人都是产品经理
人人都是产品经理
The Last Watchdog
The Last Watchdog

轶哥博客

blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog
blog
2020-07-21 · via 轶哥博客

在开发博客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

通过拼接路径并直接返回图片Header头(Content-Type是对应图片的格式)的方式,方便直接在前端<img>标签中引用图片,浏览器兼容性更好。实际使用时建议同步下载图片后上传到对象存储。