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

如何编写HTACCESS规则将指定文件夹下的所有文件请求转发至PHP校验页面并携带查询参数

如何编写HTACCESS规则将指定文件夹下的所有文件请求转发至PHP校验页面并携带查询参数

我来帮你搞定这个需求!核心思路是用.htaccess把所有指向customers文件夹下的文件请求,重写到你的check.php脚本,同时把请求的文件路径和token参数传递过去,由PHP来处理权限校验和文件流输出。

一、编写data目录下的.htaccess规则

首先,在你的example.com/data/目录下创建或修改.htaccess文件,添加以下规则:

# 启用Apache重写引擎(必须开启,否则规则无效)
RewriteEngine On

# 排除对check.php本身的请求,避免无限循环重写
RewriteCond %{REQUEST_URI} !/data/check\.php$ [NC]

# 确保请求的是实际存在的文件(可选,但能过滤掉对不存在文件的无效请求)
RewriteCond %{REQUEST_FILENAME} -f

# 把customers文件夹下的所有文件请求转发到check.php,携带文件路径和原token参数
RewriteRule ^customers/(.*)$ check.php?file=customers/$1 [L,QSA]

规则解释:

  • RewriteEngine On:开启Apache的URL重写模块,这是所有重写规则的前提(如果你的服务器没开启mod_rewrite,需要先在Apache配置里启用)。
  • 排除check.php的规则:如果不加上这条,当check.php被请求时也会被重写,导致无限循环。
  • %{REQUEST_FILENAME} -f:只对实际存在的文件生效,避免把不存在的文件请求也转发给PHP,减少无效请求。
  • RewriteRule的QSA标志:会自动把原请求的查询参数(比如token=1234)追加到新的URL上,这样check.php就能直接拿到token参数,不用手动拼接。
  • [L]标志:表示这是最后一条规则,匹配到后就停止执行后续重写规则。

二、check.php的核心校验与文件输出逻辑

接下来你需要完善data/check.php的代码,处理token校验、文件安全检查和文件流输出。这里给你一个通用的示例框架,你可以根据自己的业务逻辑调整:

<?php
// 1. 获取请求参数
$requestedFile = $_GET['file'] ?? '';
$userToken = $_GET['token'] ?? '';

// 2. 关键:防止路径遍历攻击(必须做,避免恶意用户访问服务器上的敏感文件)
$allowedBaseDir = realpath(__DIR__ . '/customers');
$targetFile = realpath(__DIR__ . '/' . $requestedFile);

// 验证目标文件是否在允许的customers目录范围内
if (!$targetFile || strpos($targetFile, $allowedBaseDir) !== 0) {
    http_response_code(403);
    echo "访问被拒绝:非法文件路径";
    exit;
}

// 3. 验证token的合法性(这里替换成你自己的业务逻辑)
// 示例:比如从数据库查询该文件对应的有效token,或者验证登录用户的权限
$isTokenValid = false;
// 注意:下面只是模拟校验,实际要换成你的真实逻辑(比如查库、会话验证等)
if ($userToken === '1234') {
    $isTokenValid = true;
}

if (!$isTokenValid) {
    http_response_code(403);
    echo "访问被拒绝:无效的Token";
    exit;
}

// 4. 检查文件是否存在且可读
if (!file_exists($targetFile) || !is_readable($targetFile)) {
    http_response_code(404);
    echo "文件不存在或无法读取";
    exit;
}

// 5. 设置正确的文件MIME类型,确保浏览器能正确渲染(比如PDF、图片、文本文件)
$mimeType = mime_content_type($targetFile);
header("Content-Type: $mimeType");

// 可选:如果想让用户下载文件而不是在线预览,取消下面这行注释
// header("Content-Disposition: attachment; filename=\"" . basename($targetFile) . "\"");

// 6. 流式输出文件内容(高效输出大文件,不用一次性读取到内存)
readfile($targetFile);
exit;

代码关键点说明:

  • 路径遍历防护:用realpath把相对路径转换成绝对路径,再检查是否在允许的customers目录下,彻底杜绝../../etc/passwd这类恶意路径请求。
  • Token校验:这里的示例是固定token,实际场景中你可以根据文件路径查询数据库中的有效共享token,或者验证当前登录用户的权限(比如只有文件所属用户才能访问)。
  • MIME类型设置:mime_content_type能自动识别文件类型,确保浏览器正确渲染PDF、图片等文件。
  • 流式输出:readfile是PHP输出文件最高效的方式,适合处理大文件,不会占用过多内存。

三、额外优化建议

  • 禁止目录索引:在.htaccess里加上Options -Indexes,防止用户直接访问customers目录看到所有文件列表。
  • 处理目录请求:如果不想让用户访问customers目录本身,可以在RewriteCond里加上RewriteCond %{REQUEST_FILENAME} !-d,排除对目录的请求。
  • 断点续传支持:如果你的文件很大,可以添加对HTTP Range头的支持,让用户能断点续传下载(需要额外处理,可选)。

备注:内容来源于stack exchange,提问作者Devanshu Goyal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 10:18:01