我之前写过一个更完善的,支持反代任意 URL,支持 GET/POST 等多种请求,适配了 headers 和重定向,但是对大文件支持不好,所以一直没发出来😂现在发出来,看看大家有什么优化方法
<?php
// 获取请求信息
$request_url = $_SERVER["QUERY_STRING"];
$request_method = $_SERVER["REQUEST_METHOD"];
$request_header = getallheaders();
$request_body = file_get_contents('php://input');
// 转换请求头
// 从请求的 url 中提取 host 字段
$request_host = parse_url($request_url)["host"];
$formatted_header = ["Host: $request_host"];
// 其他的保持原请求头不变
foreach ($request_header as $key => $value) {
$formatted_header[] = $key . ": " . $value;
}
// 开始请求
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $request_url,
CURLOPT_CUSTOMREQUEST => $request_method,
CURLOPT_HTTPHEADER => $formatted_header,
CURLOPT_POSTFIELDS => $request_body,
CURLOPT_RETURNTRANSFER => true, // 返回响应而不是直接输出
CURLOPT_HEADER => true // 返回响应头
]);
$response = curl_exec($ch);
// curl 错误处理
if ($response === false) {
http_response_code(500);
echo "Curl error: " . curl_error($ch);
curl_close($ch);
exit;
}
// 获取状态码
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// 获取响应头长度
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $header_size);
$body = substr($response, $header_size);
curl_close($ch);
// 将头信息逐行添加到响应头中
foreach (explode("\r\n", $header) as $header_line) {
// 如果有重定向就替换重定向的 url 是被代理过得
if (stripos($header_line, "Location: ") === 0) {
header("Location: " . $_SERVER["SCRIPT_NAME"]. "?" . trim(substr($header_line, 9)));
}
// 其他的保持原响应头不变
elseif (!empty($header_line)) {
header($header_line);
}
}
// 返回状态码
http_response_code($code);
// 返回响应体
echo($body);
?>
不需要配置伪静态,直接访问 https://example.com/index.php?需要代理的URL
即可