You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用PHP隐藏外部网站的原始下载链接?

解决方案:隐藏外部文件URL实现下载

原代码的问题

  • 你把完整的外部URL作为下载文件名,会导致用户下载的文件名变成一串混乱的URL字符,完全不符合预期。
  • 直接用readfile()读取HTTPS URL依赖PHP的allow_url_fopen配置,很多服务器默认限制这个功能,导致无法正常读取文件。
  • 缺少文件长度、缓存控制等必要HTTP头部,可能引发下载中断、进度显示异常等问题。

方案一:使用readfile(需开启allow_url_fopen)

这种方式简单直接,但需要服务器允许PHP读取外部URL:

<?php
// 用白名单映射ID和文件URL,避免恶意请求
$fileMap = [
    '1' => 'https://externalsite.com/20230113100300if_/https%3A%2F%2Fs38.123apps.com%2Fvconv%2Fd%2F63c12a662da0e_mkv_ymfVHPvq.mkv',
    // 可添加更多ID对应文件的条目
];

$id = $_GET['id'] ?? '';
if (!isset($fileMap[$id])) {
    die('无效请求');
}

$fileUrl = $fileMap[$id];

// 从URL中提取真实文件名,也可手动指定如$filename = "video.mkv"
$parsedUrl = parse_url($fileUrl);
$pathParts = explode('/', $parsedUrl['path']);
$filename = end($pathParts);

// 获取文件大小
$filesize = filesize($fileUrl);

// 设置正确的HTTP头部
header('Content-Type: video/x-matroska'); // MKV文件的标准MIME类型
header('Content-Disposition: attachment; filename="' . rawurlencode($filename) . '"');
header('Content-Length: ' . $filesize);
header('Cache-Control: no-cache');
header('Pragma: no-cache');

// 输出文件内容
readfile($fileUrl);
exit;
?>

方案二:使用cURL(更稳定,不依赖allow_url_fopen)

如果服务器禁用了allow_url_fopen,用cURL是更可靠的选择:

<?php
// 同样使用白名单映射ID和文件URL
$fileMap = [
    '1' => 'https://externalsite.com/20230113100300if_/https%3A%2F%2Fs38.123apps.com%2Fvconv%2Fd%2F63c12a662da0e_mkv_ymfVHPvq.mkv',
];

$id = $_GET['id'] ?? '';
if (!isset($fileMap[$id])) {
    die('无效请求');
}

$fileUrl = $fileMap[$id];

// 解析文件名
$parsedUrl = parse_url($fileUrl);
$pathParts = explode('/', $parsedUrl['path']);
$filename = end($pathParts);

// 初始化cURL请求
$ch = curl_init($fileUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 自动处理重定向

$response = curl_exec($ch);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$body = substr($response, $headerSize); // 分离响应头和文件内容
$filesize = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD); // 获取文件大小

curl_close($ch);

// 设置HTTP头部
header('Content-Type: video/x-matroska');
header('Content-Disposition: attachment; filename="' . rawurlencode($filename) . '"');
header('Content-Length: ' . $filesize);
header('Cache-Control: no-cache');
header('Pragma: no-cache');

// 输出文件内容
echo $body;
exit;
?>

关键注意事项

  • 必须使用白名单映射(如代码中的$fileMap),绝对不能直接用$_GET['id']拼接URL,否则会被恶意利用来下载任意外部文件,造成安全风险。
  • 确保服务器开启了对应功能:方案一需要allow_url_fopen = On,方案二需要开启cURL扩展。
  • 使用video/x-matroska作为MIME类型,比通用的application/octet-stream更友好,浏览器能正确识别文件类型。

内容的提问来源于stack exchange,提问作者Zamani Vogue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 00:20:30