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

如何用PHP检测用户下载行为?JS怎样访问数据库?

检测用户下载行为的实现方案

一、PHP 检测下载行为(推荐可靠方案)

最稳妥的方式是通过 PHP 脚本作为下载的中转处理程序,既能确保每次下载都被记录,又能提升文件安全性(避免文件被直接访问)。具体步骤如下:

1. 准备工作

  • 将待下载的程序文件移至网站根目录以外的安全路径(比如 /var/www/private/),防止用户直接通过 URL 访问。
  • 创建一个 downloads 数据表用于存储下载记录(可根据需求调整字段):
CREATE TABLE downloads (
    id INT AUTO_INCREMENT PRIMARY KEY,
    ip VARCHAR(45) NOT NULL,
    file_name VARCHAR(255) NOT NULL,
    download_time DATETIME NOT NULL,
    country VARCHAR(100),
    region VARCHAR(100),
    city VARCHAR(100)
);

2. 编写下载处理脚本(download.php)

复用你现有的数据库操作类 $dbcls,实现记录下载日志+输出文件的逻辑:

<?php
// 引入数据库类(替换为你的实际路径)
require_once 'path/to/your/dbclass.php';
$dbcls = new YourDBClass();

// 校验允许下载的文件列表,防止恶意路径遍历
$allowed_files = ['my_program.exe', 'tool.zip'];
$target_file = isset($_GET['file']) ? $_GET['file'] : '';

if (!in_array($target_file, $allowed_files)) {
    die('无效的下载请求');
}

// 文件实际存储路径
$file_path = '/var/www/private/' . $target_file;
if (!file_exists($file_path)) {
    die('文件不存在');
}

// 记录下载行为到数据库
$user_ip = $_SERVER['REMOTE_ADDR'];
// 复用你的地理位置获取函数
$location_data = get_location2($user_ip);
$country = $location_data ? $dbcls->escape_string($location_data->country) : '';
$region = $location_data ? $dbcls->escape_string($location_data->subdivision) : '';
$city = $location_data ? $dbcls->escape_string($location_data->city) : '';

$insert_qry = "INSERT INTO downloads (ip, file_name, download_time, country, region, city)
               VALUES ('" . $dbcls->escape_string($user_ip) . "', 
                       '" . $dbcls->escape_string($target_file) . "', 
                       NOW(), 
                       '" . $country . "', 
                       '" . $region . "', 
                       '" . $city . "')";
$dbcls->query_command($insert_qry);

// 发送文件给用户
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file_path) . '"');
header('Content-Length: ' . filesize($file_path));
// 大文件推荐用分块读取代替 readfile,避免内存溢出
readfile($file_path);
exit;
?>

3. 前端下载链接

将原文件链接替换为指向 PHP 脚本的链接:

<a href="download.php?file=my_program.exe">下载我的程序</a>

二、JavaScript 辅助方案(无法直接操作数据库)

JavaScript 本身不能直接连接数据库,必须通过调用后端 PHP 接口实现日志记录。这种方式适合辅助场景,但无法保证 100% 可靠(比如用户点击后立即关闭页面可能导致请求中断)。

1. 前端 JS 代码

为下载链接添加点击事件,通过 AJAX 发送日志请求:

document.querySelectorAll('.download-link').forEach(link => {
    link.addEventListener('click', async (e) => {
        try {
            // 异步发送日志请求,不阻塞下载
            await fetch('log_download.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: 'file=' + encodeURIComponent(link.dataset.file)
            });
        } catch (err) {
            // 日志失败不影响下载,仅在控制台输出错误
            console.error('下载日志记录失败:', err);
        }
    });
});

对应的 HTML 链接:

<a href="my_program.exe" class="download-link" data-file="my_program.exe">下载程序</a>

2. 后端日志接口(log_download.php)

接收 JS 请求并写入数据库:

<?php
require_once 'path/to/your/dbclass.php';
$dbcls = new YourDBClass();

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['file'])) {
    $file_name = $dbcls->escape_string($_POST['file']);
    $user_ip = $_SERVER['REMOTE_ADDR'];
    $location_data = get_location2($user_ip);
    
    $country = $location_data ? $dbcls->escape_string($location_data->country) : '';
    $region = $location_data ? $dbcls->escape_string($location_data->subdivision) : '';
    $city = $location_data ? $dbcls->escape_string($location_data->city) : '';

    $insert_qry = "INSERT INTO downloads (ip, file_name, download_time, country, region, city)
                   VALUES ('" . $dbcls->escape_string($user_ip) . "', 
                           '" . $file_name . "', 
                           NOW(), 
                           '" . $country . "', 
                           '" . $region . "', 
                           '" . $city . "')";
    $dbcls->query_command($insert_qry);
}
?>

注意事项

  • 优先选择 PHP 中转方案:能确保每一次成功的下载都被记录,安全性和可靠性更高。
  • 安全校验:永远不要直接使用用户输入的文件名构造文件路径,必须通过白名单校验防止目录遍历攻击。
  • 大文件优化:对于超大文件,建议使用服务器的 X-Sendfile(Apache)或 X-Accel-Redirect(Nginx)特性,提升下载效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 17:50:24