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

如何限制PDF文件直接访问,仅允许从指定页面跳转访问?

嘿,这个需求其实挺常见的,我给你几个可行的方案,你可以根据自己的技术栈和安全要求来选:

方案一:用.htaccess基于Referer限制访问

这是最快速的实现方式,核心思路是只允许来自你本站(尤其是index.php)的请求访问PDF,直接访问或者外部链接过来的都拦截。

你可以在项目根目录的.htaccess里添加以下规则:

RewriteEngine On

# 阻止直接访问assets/docs/document.pdf,仅允许来自本站的请求
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?domain\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule ^assets/docs/document\.pdf$ - [F,L]

说明:

  • %{HTTP_REFERER} !^https?://(www\.)?domain\.com/:检查请求的来源是否不是你的域名(NC表示不区分大小写)
  • !^$:排除空Referer的情况(有些浏览器或隐私插件会不发送Referer,避免误拦)
  • [F,L]:返回403禁止访问,并且停止后续规则执行

⚠️ 注意:Referer是可以被伪造的,这个方案适合普通场景,对安全性要求极高的话建议用下面的PHP方案。

方案二:用PHP做文件代理(更安全可靠)

这个方案会把PDF文件移出Web可直接访问的目录,通过PHP脚本中转访问,同时验证请求的合法性,彻底避免直接访问的可能。

步骤:

  1. 移动PDF文件:把document.pdf从assets/docs/移到Web根目录外面,比如新建一个private_files/文件夹(这个目录不能通过浏览器直接访问)。
  2. 创建PHP代理脚本:在项目根目录新建get-document.php,内容如下:
<?php
session_start();

// 验证访问合法性:要么来自index.php的跳转,要么已有会话标记
$isAllowed = false;
$referer = $_SERVER['HTTP_REFERER'] ?? '';

// 检查是否从index.php页面跳转过来
if (strpos($referer, 'index.php') !== false || strpos($referer, $_SERVER['HTTP_HOST']) !== false) {
    $isAllowed = true;
    // 标记会话,后续同一会话内访问无需再验证Referer
    $_SESSION['pdf_access_allowed'] = true;
}
// 或者如果用户需要登录才能看,这里可以加登录状态验证
// else if (isset($_SESSION['user_logged_in'])) { $isAllowed = true; }

if (!$isAllowed && !isset($_SESSION['pdf_access_allowed'])) {
    header('HTTP/1.1 403 Forbidden');
    exit('Access Denied: You can only access this document from the main page.');
}

// 输出PDF内容
$pdfPath = '../private_files/document.pdf';
if (!file_exists($pdfPath)) {
    header('HTTP/1.1 404 Not Found');
    exit('Document not found.');
}

header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="document.pdf"');
header('Content-Length: ' . filesize($pdfPath));
readfile($pdfPath);
exit;
  1. 修改index.php里的链接:把原来指向assets/docs/document.pdf的链接改成:
<a href="get-document.php">查看PDF文档</a>

这个方案的优势是:PDF文件不在Web公开目录,即使知道文件名也无法直接访问;还可以扩展验证逻辑(比如登录状态、用户权限等)。

方案三:直接将PDF嵌入页面(彻底隐藏链接)

如果不想让用户拿到PDF的直接下载链接,可以把PDF嵌入到页面里,用浏览器直接渲染,甚至用JS库把PDF转成HTML渲染。

方法1:用iframe嵌入(简单)

直接在index.php里用iframe加载代理后的PDF:

<iframe src="get-document.php" width="100%" height="800px" frameborder="0" title="PDF Document"></iframe>

方法2:用PDF.js渲染(更灵活)

PDF.js是Mozilla的开源库,可以把PDF渲染成HTML元素,完全控制展示效果,同时避免暴露原始PDF链接。

  1. 下载PDF.js库,解压后放到assets/pdfjs/目录里;
  2. 在index.php里添加以下代码:
<div id="pdf-container" style="width: 100%; height: 800px;"></div>

<script src="assets/pdfjs/build/pdf.min.js"></script>
<script>
// 加载并渲染PDF
async function renderPDF() {
    // 这里用代理脚本的地址,确保验证通过
    const pdf = await pdfjsLib.getDocument('get-document.php').promise;
    
    // 渲染第一页(可以扩展成多页渲染)
    const page = await pdf.getPage(1);
    const viewport = page.getViewport({ scale: 1.5 });
    
    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');
    canvas.width = viewport.width;
    canvas.height = viewport.height;
    
    document.getElementById('pdf-container').appendChild(canvas);
    await page.render({ canvasContext: context, viewport: viewport }).promise;
}

// 确保从index页面加载才执行渲染
if (document.referrer.includes('index.php') || window.location.pathname.includes('index.php')) {
    renderPDF();
} else {
    document.getElementById('pdf-container').innerHTML = '<p>请从主页面访问文档</p>';
}
</script>

这个方案的好处是用户无法直接右键下载原始PDF(除非懂技术去抓接口,但普通用户做不到),还能自定义PDF的展示样式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:40:06