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

如何从WordPress站点B获取X-Sendfile传输的远程文件?

解决WordPress站点代理X-Sendfile远程下载的思路

先分析你之前两种方法失败的原因:

  • 方法1(download_url):WordPress的download_url函数主要用于将文件下载到本地服务器存储,它的URL校验逻辑会检查目标是否返回可识别的文件内容,而站点A返回的是X-Sendfile头(而非直接文件内容),导致函数判定URL无效。
  • 方法2(PhpXsendfile直接传远程URL):X-Sendfile机制的核心是让Web服务器读取本地文件并发送给客户端,它不支持远程URL,因此直接传入远程地址会导致服务器找不到对应本地文件,触发错误。

下面是三种可行的解决思路:

方案1:PHP反向代理(WordPress环境兼容)

使用WordPress内置的WP_Http类请求站点A的下载链接,获取响应头和文件内容后转发给客户端,相当于站点B做一层中转。这种方式无需服务器配置,代码层面即可实现:

if (!empty($_GET['download'])) {
    $remote_download_url = 'https://a.com/?download=' . urlencode($_GET['download']);
    $http_client = new WP_Http();
    
    // 配置流式下载到临时文件,避免大文件占用过多内存
    $response = $http_client->get($remote_download_url, [
        'timeout' => 300, // 根据文件大小调整超时时间
        'stream' => true,
        'filename' => tempnam(sys_get_temp_dir(), 'wp_proxy_download_'),
    ]);

    if (is_wp_error($response)) {
        status_header(404);
        exit('下载失败:' . $response->get_error_message());
    }

    // 转发站点A返回的下载相关响应头
    $remote_headers = $response['headers'];
    if (isset($remote_headers['Content-Disposition'])) {
        header('Content-Disposition: ' . $remote_headers['Content-Disposition']);
    }
    if (isset($remote_headers['Content-Type'])) {
        header('Content-Type: ' . $remote_headers['Content-Type']);
    }
    if (isset($remote_headers['Content-Length'])) {
        header('Content-Length: ' . $remote_headers['Content-Length']);
    }

    // 输出文件内容并清理临时文件
    readfile($response['filename']);
    unlink($response['filename']);
    exit;
}

注意:如果是超大文件,建议进一步优化临时文件处理逻辑,避免磁盘占用过高。

方案2:Web服务器反向代理(性能最优)

如果拥有站点B的服务器配置权限,直接在Web服务器(Nginx/Apache)层面配置反向代理,让请求直接转发到站点A,这种方式完全绕过PHP,性能最佳,适合大文件场景。

Nginx配置示例

location ~ ^/\?download= {
    proxy_pass https://a.com$request_uri;
    proxy_set_header Host a.com;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    # 若站点A使用Nginx的X-Accel-Redirect(替代X-Sendfile),需转发对应头
    # proxy_pass_header X-Accel-Redirect;
}

Apache配置示例

RewriteEngine On
RewriteCond %{QUERY_STRING} ^download=(.*)$
RewriteRule ^(.*)$ https://a.com/$1?download=%1 [P,L]
# 确保已启用mod_proxy、mod_proxy_http和mod_rewrite模块

方案3:302重定向(最简单但暴露源站)

如果不介意访客跳转到站点A的URL,可以直接在站点B做302重定向,代码最简单:

if (!empty($_GET['download'])) {
    $remote_url = 'https://a.com/?download=' . urlencode($_GET['download']);
    wp_redirect($remote_url);
    exit;
}

方案对比

  • Web服务器代理:性能最优,无PHP开销,适合大文件,但需要服务器配置权限。
  • PHP代理:无需服务器配置,兼容性强,但大文件可能存在内存/超时问题,需优化。
  • 302重定向:实现最简单,但访客会跳转到站点A的URL,暴露源站地址。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 18:09:23