吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 622|回复: 4
收起左侧

[学习记录] webdav创建分享链接

[复制链接]
ChiZhu 发表于 2026-3-23 10:58
本帖最后由 ChiZhu 于 2026-3-23 12:51 编辑

都是AI编写

WebDAV 文件管理器 - 完整使用指南

📖 项目简介

这是一个基于纯 PHP 开发的 WebDAV 文件管理器,无需任何第三方 SDK,支持:

  • ✅ 浏览目录和文件列表
  • ✅ 文件上传(支持大文件流式上传)
  • ✅ 文件下载(支持断点续传)
  • ✅ 文件/目录删除
  • 临时 Token 分享链接(24小时有效,不暴露密码)
  • ✅ 图片直接显示(无需下载即可查看)
  • ✅ 支持中文文件名
  • ✅ 美观的现代化界面

🚀 功能特点

1. 文件浏览

  • 点击文件夹图标可进入子目录
  • 显示文件大小、最后修改时间
  • 自动识别文件类型(目录/文件)

2. 文件上传

  • 支持任意类型文件上传
  • 进度提示(浏览器原生)
  • 自动处理文件名编码

3. 文件下载

  • 直接下载到本地
  • 支持大文件(通过流式传输,内存占用小)

4. 临时分享链接 ⭐

  • 生成 24 小时有效期的分享链接
  • 链接中不包含 WebDAV 密码
  • 图片链接可直接在浏览器中显示
  • 文本文件可直接查看内容

5. 安全特性

  • 所有操作需通过 WebDAV 认证
  • 分享链接使用随机 Token,无法伪造
  • 自动清理过期的分享 Token
  • 路径遍历攻击防护

📦 安装部署

环境要求

  • PHP 5.6 或更高版本
  • cURL 扩展
  • SimpleXML 扩展
  • 文件写入权限(用于存储分享 Token)

快速安装

  1. 下载文件
    将以下文件上传到您的 PHP 服务器同一目录:

    • index.php - 主文件管理器
    • share.php - 分享代理
  2. 配置认证信息
    编辑 index.phpshare.php,修改以下配置:
    > php
    > define('WEBDAV_URL', 'https://your-webdav-server.com/dav');
    > define('WEBDAV_USER', 'your_username');
    > define('WEBDAV_PASS', 'your_password');



屏幕截图 2026-03-23 124519.png
首页
屏幕截图 2026-03-23 102629.png
文件夹里  都可以创建分享链接
屏幕截图 2026-03-23 102737.png

以infini-cloud写的,不知道其它webdav能不能用
index.php  修改以下
> // 设置管理密码(请修改为强密码)
>  $admin_password = 'your_strong_password_here';
> define('WEBDAV_URL', 'webdav服务器链接');
> define('WEBDAV_USER', '用户名');
> define('WEBDAV_PASS', '密码');


[PHP] 纯文本查看 复制代码
<?php
/**
 * WebDAV 文件管理器(含临时 Token 分享)
 * 支持:浏览目录、上传、下载、删除、生成临时分享链接
 */

header('Content-Type: text/html; charset=utf-8');

session_start();

// 设置管理密码(请修改为强密码)
$admin_password = 'your_strong_password_here';

// 检查是否已登录
if (!isset($_SESSION['webdav_logged']) || $_SESSION['webdav_logged'] !== true) {
    // 处理登录表单
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['login_password']) && $_POST['login_password'] === $admin_password) {
        $_SESSION['webdav_logged'] = true;
        // 刷新页面
        header('Location: ' . $_SERVER['PHP_SELF']);
        exit;
    }
    // 显示登录界面
    ?>
    <!DOCTYPE html>
    <html>
    <head><meta charset="UTF-8"><title>登录</title></head>
    <body style="font-family: sans-serif; text-align:center; margin-top:100px;">
        <form method="post">
            <h2>WebDAV 文件管理器 - 登录</h2>
            <input type="password" name="login_password" placeholder="请输入管理密码" required>
            <button type="submit">登录</button>
        </form>
    </body>
    </html>
    <?php
    exit;
}
$missingExtensions = [];
if (!extension_loaded('curl')) $missingExtensions[] = 'cURL';
if (!extension_loaded('SimpleXML')) $missingExtensions[] = 'SimpleXML';
if (!empty($missingExtensions)) {
    die('缺少必需的 PHP 扩展:' . implode(', ', $missingExtensions));
}

define('WEBDAV_URL', 'webdav服务器链接');
define('WEBDAV_USER', '用户名');
define('WEBDAV_PASS', '密码');

// Token 存储文件
$tokenFile = __DIR__ . '/share_tokens.json';
if (!file_exists($tokenFile)) {
    file_put_contents($tokenFile, json_encode([]));
}

class WebDAVClient
{
    private $baseUrl;
    private $basePath;
    private $username;
    private $password;

    public function __construct($baseUrl, $username, $password)
    {
        $this->baseUrl = rtrim($baseUrl, '/');
        $this->basePath = parse_url($this->baseUrl, PHP_URL_PATH) ?: '/';
        $this->username = $username;
        $this->password = $password;
    }

    private function request($method, $path = '', $options = [])
    {
        $url = $this->baseUrl . '/' . ltrim($path, '/');
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        curl_setopt($ch, CURLOPT_USERPWD, $this->username . ':' . $this->password);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

        $headers = isset($options['headers']) ? $options['headers'] : [];
        if (!empty($options['body'])) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, $options['body']);
            $headers[] = 'Content-Length: ' . strlen($options['body']);
        }
        if (!empty($headers)) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);

        return ['body' => $response, 'code' => $httpCode, 'error' => $error];
    }

    public function listFiles($path = '')
    {
        $normPath = $path;
        if ($normPath !== '' && substr($normPath, -1) !== '/') {
            $normPath = $normPath . '/';
        }

        $result = $this->request('PROPFIND', $normPath, [
            'headers' => ['Depth: 1', 'Content-Type: application/xml; charset=utf-8'],
            'body' => '<?xml version="1.0" encoding="utf-8"?>
<propfind xmlns="DAV:">
    <prop>
        <resourcetype/>
        <getcontentlength/>
        <getlastmodified/>
    </prop>
</propfind>'
        ]);

        if ($result['code'] !== 207) {
            throw new Exception("PROPFIND 失败: HTTP {$result['code']}");
        }

        $xml = simplexml_load_string($result['body']);
        if ($xml === false) {
            throw new Exception("无法解析 XML 响应");
        }

        $responses = $xml->xpath('//*[local-name()="response"]');
        if (empty($responses)) {
            return [];
        }

        $files = [];
        foreach ($responses as $response) {
            $href = '';
            $hrefNodes = $response->xpath('.//*[local-name()="href"]');
            if (!empty($hrefNodes)) {
                $href = (string)$hrefNodes[0];
            }
            if (empty($href)) continue;

            $hrefPath = parse_url($href, PHP_URL_PATH);
            if (!$hrefPath) $hrefPath = $href;
            $relative = ltrim(str_replace($this->basePath, '', $hrefPath), '/');
            if ($relative === '' || $relative === $path || $relative === $path . '/') {
                continue;
            }

            $name = basename($relative);
            $isDir = false;
            $size = 0;
            $lastModified = '';

            $propstats = $response->xpath('.//*[local-name()="propstat"]');
            foreach ($propstats as $propstat) {
                $statusNodes = $propstat->xpath('.//*[local-name()="status"]');
                $status = !empty($statusNodes) ? (string)$statusNodes[0] : '';
                if (strpos($status, '200') !== false) {
                    $propNodes = $propstat->xpath('.//*[local-name()="prop"]');
                    if (!empty($propNodes)) {
                        $prop = $propNodes[0];
                        $resourcetypeNodes = $prop->xpath('.//*[local-name()="resourcetype"]');
                        if (!empty($resourcetypeNodes)) {
                            $collection = $resourcetypeNodes[0]->xpath('.//*[local-name()="collection"]');
                            $isDir = !empty($collection);
                        }
                        $sizeNodes = $prop->xpath('.//*[local-name()="getcontentlength"]');
                        if (!empty($sizeNodes)) {
                            $size = (int)$sizeNodes[0];
                        }
                        $lastmodNodes = $prop->xpath('.//*[local-name()="getlastmodified"]');
                        if (!empty($lastmodNodes)) {
                            $lastModified = (string)$lastmodNodes[0];
                        }
                    }
                    break;
                }
            }

            $files[] = [
                'name' => urldecode($name),
                'raw_name' => $name,
                'type' => $isDir ? 'dir' : 'file',
                'size' => $size,
                'lastmodified' => $lastModified,
                'href' => $href
            ];
        }
        return $files;
    }

    public function uploadFile($localPath, $remotePath)
    {
        if (!file_exists($localPath)) {
            throw new Exception("本地文件不存在: $localPath");
        }
        $content = file_get_contents($localPath);
        if ($content === false) {
            throw new Exception("无法读取本地文件: $localPath");
        }

        $result = $this->request('PUT', $remotePath, [
            'body' => $content,
            'headers' => ['Content-Type' => 'application/octet-stream']
        ]);

        if ($result['code'] !== 201 && $result['code'] !== 204) {
            throw new Exception("上传失败: HTTP {$result['code']}");
        }
        return true;
    }

    public function downloadFile($remotePath, $localPath)
    {
        $result = $this->request('GET', $remotePath);
        if ($result['code'] !== 200) {
            throw new Exception("下载失败: HTTP {$result['code']}");
        }
        if (file_put_contents($localPath, $result['body']) === false) {
            throw new Exception("无法写入本地文件: $localPath");
        }
        return true;
    }

    public function deleteFile($remotePath)
    {
        $result = $this->request('DELETE', $remotePath);
        if ($result['code'] !== 200 && $result['code'] !== 204) {
            throw new Exception("删除失败: HTTP {$result['code']}");
        }
        return true;
    }

    public function formatSize($bytes)
    {
        if ($bytes === 0) return '0 B';
        $units = ['B', 'KB', 'MB', 'GB', 'TB'];
        $i = floor(log($bytes, 1024));
        return round($bytes / pow(1024, $i), 2) . ' ' . $units[$i];
    }
}

// 处理操作
$action = isset($_GET['action']) ? $_GET['action'] : '';
$path = isset($_GET['path']) ? trim($_GET['path'], '/') : '';
$file = isset($_GET['file']) ? $_GET['file'] : '';
$deleteFile = isset($_GET['delete']) ? $_GET['delete'] : '';

$client = new WebDAVClient(WEBDAV_URL, WEBDAV_USER, WEBDAV_PASS);
$message = '';
$error = '';

try {
    // 生成分享 Token 的 AJAX 接口
    if ($action === 'create_share' && isset($_POST['file_path'])) {
        $filePath = $_POST['file_path'];
        $token = bin2hex(random_bytes(16));
        $expire = time() + 86400; // 24小时
        $tokens = json_decode(file_get_contents($tokenFile), true);
        $tokens[$token] = ['path' => $filePath, 'expire' => $expire];
        file_put_contents($tokenFile, json_encode($tokens));
        $shareUrl = (isset($_SERVER['HTTPS']) ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . dirname($_SERVER['SCRIPT_NAME']) . '/share.php?token=' . $token;
        header('Content-Type: application/json');
        echo json_encode(['url' => $shareUrl]);
        exit;
    }

    if ($action === 'delete' && !empty($deleteFile)) {
        $targetPath = $path ? $path . '/' . $deleteFile : $deleteFile;
        $client->deleteFile($targetPath);
        $message = "已删除: " . htmlspecialchars($deleteFile);
        header('Location: ?path=' . urlencode($path));
        exit;
    }

    if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['upload_file'])) {
        $uploadFile = $_FILES['upload_file'];
        if ($uploadFile['error'] === UPLOAD_ERR_OK) {
            $remotePath = $path ? $path . '/' . basename($uploadFile['name']) : basename($uploadFile['name']);
            $client->uploadFile($uploadFile['tmp_name'], $remotePath);
            $message = "上传成功: " . htmlspecialchars(basename($uploadFile['name']));
        } else {
            $error = "上传失败: " . $uploadFile['error'];
        }
        header('Location: ?path=' . urlencode($path));
        exit;
    }

    if ($action === 'download' && !empty($file)) {
        $remotePath = $path ? $path . '/' . $file : $file;
        $ch = curl_init(WEBDAV_URL . '/' . ltrim($remotePath, '/'));
        curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        curl_setopt($ch, CURLOPT_USERPWD, WEBDAV_USER . ':' . WEBDAV_PASS);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="' . rawurlencode($file) . '"');
        curl_exec($ch);
        curl_close($ch);
        exit;
    }

    $files = $client->listFiles($path);

} catch (Exception $e) {
    $error = $e->getMessage();
    $files = [];
}

$parentPath = '';
if (!empty($path)) {
    $parts = explode('/', $path);
    array_pop($parts);
    $parentPath = implode('/', $parts);
}
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>WebDAV 文件管理器</title>
    <style>
        body { font-family: 'Segoe UI', Arial, sans-serif; margin: 20px; background: #f5f5f5; }
        .container { max-width: 1200px; margin: 0 auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
        h2 { color: #333; margin-top: 0; }
        .nav-bar { margin-bottom: 20px; padding: 10px; background: #f0f0f0; border-radius: 5px; }
        .current-path { font-family: monospace; background: #e9ecef; padding: 5px 10px; border-radius: 3px; display: inline-block; }
        .btn { display: inline-block; padding: 6px 12px; margin: 2px; background: #007bff; color: white; text-decoration: none; border-radius: 4px; border: none; cursor: pointer; font-size: 14px; }
        .btn-danger { background: #dc3545; }
        .btn-success { background: #28a745; }
        .btn-sm { padding: 3px 8px; font-size: 12px; }
        .btn:hover { opacity: 0.9; }
        table { border-collapse: collapse; width: 100%; background: white; box-shadow: 0 1px 3px rgba(0,0,0,0.1); margin-top: 15px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #4CAF50; color: white; }
        tr:nth-child(even) { background-color: #f9f9f9; }
        tr:hover { background-color: #f1f1f1; }
        .dir { color: #2196F3; font-weight: bold; }
        .file { color: #333; }
        .size { text-align: right; }
        .date { font-family: monospace; }
        .message { padding: 10px; margin-bottom: 15px; border-radius: 4px; background: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
        .error { background: #f8d7da; color: #721c24; border-color: #f5c6cb; }
        .upload-form { margin-top: 20px; padding: 15px; background: #f8f9fa; border-radius: 5px; border: 1px solid #ddd; }
        .action-links a { margin-right: 8px; text-decoration: none; }
        .modal { display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.3); z-index: 1000; min-width: 400px; }
        .overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 999; }
    </style>
</head>
<body>
<div class="container">
    <h2>&#128193; WebDAV 文件管理器</h2>
    
    <?php if ($message): ?>
        <div class="message"><?= htmlspecialchars($message) ?></div>
    <?php endif; ?>
    <?php if ($error): ?>
        <div class="error"><?= htmlspecialchars($error) ?></div>
    <?php endif; ?>
    
    <div class="nav-bar">
        <strong>当前路径:</strong>
        <span class="current-path">/<?= htmlspecialchars($path) ?></span>
        <?php if ($parentPath !== '' || !empty($path)): ?>
            <a href="?path=<?= urlencode($parentPath) ?>" class="btn btn-sm">&#11014; 返回上级</a>
        <?php endif; ?>
        <a href="?path=<?= urlencode($path) ?>" class="btn btn-sm">&#128260; 刷新</a>
    </div>
    
    <?php if (empty($files)): ?>
        <p>此目录为空。</p>
    <?php else: ?>
        <table>
            <thead>
                <tr><th>名称</th><th>类型</th><th>大小</th><th>最后修改时间</th><th>操作</th></tr>
            </thead>
            <tbody>
                <?php foreach ($files as $item): ?>
                <tr>
                    <td class="<?= $item['type'] === 'dir' ? 'dir' : 'file' ?>">
                        <?php if ($item['type'] === 'dir'): ?>
                            <a href="?path=<?= urlencode($path ? $path . '/' . $item['raw_name'] : $item['raw_name']) ?>">
                                &#128193; <?= htmlspecialchars($item['name']) ?>
                            </a>
                        <?php else: ?>
                            &#128196; <?= htmlspecialchars($item['name']) ?>
                        <?php endif; ?>
                    </td>
                    <td><?= $item['type'] === 'dir' ? '目录' : '文件' ?></td>
                    <td class="size"><?= $item['type'] === 'dir' ? '-' : $client->formatSize($item['size']) ?></td>
                    <td class="date"><?= htmlspecialchars($item['lastmodified']) ?></td>
                    <td class="action-links">
                        <?php if ($item['type'] === 'file'): ?>
                            <a href="?action=download&path=<?= urlencode($path) ?>&file=<?= urlencode($item['raw_name']) ?>" class="btn btn-sm">&#11015; 下载</a>
                            <button class="btn btn-sm btn-success">&#128279; 分享</button>
                        <?php endif; ?>
                        <a href="?action=delete&path=<?= urlencode($path) ?>&delete=<?= urlencode($item['raw_name']) ?>" class="btn btn-sm btn-danger">&#128465; 删除</a>
                    </td>
                </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
    <?php endif; ?>
    
    <div class="upload-form">
        <h3>上传文件到当前目录</h3>
        <form method="post" enctype="multipart/form-data">
            <input type="file" name="upload_file" required>
            <button type="submit" class="btn btn-success">上传</button>
        </form>
    </div>
</div>

<div id="shareModal" class="modal">
    <h3>分享文件:<span id="shareFileName"></span></h3>
    <p>链接(24小时有效,不含密码):</p>
    <input type="text" id="shareLink" readonly style="width:100%; padding:8px; margin:10px 0; border:1px solid #ccc; border-radius:4px;">
    <button class="btn btn-sm btn-success">复制链接</button>
    <button class="btn btn-sm">关闭</button>
</div>
<div id="modalOverlay" class="overlay"></div>

<script>
function createShare(filePath, fileName) {
    fetch('?action=create_share', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: 'file_path=' + encodeURIComponent(filePath)
    })
    .then(res => res.json())
    .then(data => {
        document.getElementById('shareFileName').innerText = fileName;
        document.getElementById('shareLink').value = data.url;
        document.getElementById('shareModal').style.display = 'block';
        document.getElementById('modalOverlay').style.display = 'block';
    })
    .catch(err => alert('生成分享链接失败: ' + err));
}
function copyLink() {
    const link = document.getElementById('shareLink');
    link.select();
    document.execCommand('copy');
    alert('链接已复制到剪贴板');
}
function closeModal() {
    document.getElementById('shareModal').style.display = 'none';
    document.getElementById('modalOverlay').style.display = 'none';
}
document.getElementById('modalOverlay').onclick = closeModal;
</script>
</body>
</html>








share.php   修改以下
> define('WEBDAV_URL', 'webdav服务器链接');
> define('WEBDAV_USER', '用户名');
> define('WEBDAV_PASS', '密码');


[PHP] 纯文本查看 复制代码
<?php
// share.php - 分享代理,独立运行,不包含其他文件
if (ob_get_level()) ob_end_clean();  // 清除可能存在的输出缓冲


define('WEBDAV_URL', '链接');
define('WEBDAV_USER', '用户名');
define('WEBDAV_PASS', '密码');

$token = $_GET['token'] ?? '';
if (empty($token)) {
    http_response_code(400);
    exit('Missing token');
}

$tokenFile = __DIR__ . '/share_tokens.json';
if (!file_exists($tokenFile)) {
    http_response_code(404);
    exit('Invalid token');
}

$tokens = json_decode(file_get_contents($tokenFile), true);
if (!isset($tokens[$token])) {
    http_response_code(404);
    exit('Invalid token');
}

$data = $tokens[$token];
if ($data['expire'] < time()) {
    unset($tokens[$token]);
    file_put_contents($tokenFile, json_encode($tokens));
    http_response_code(410);
    exit('Share link expired');
}

$filePath = $data['path'];
if (strpos($filePath, '..') !== false) {
    http_response_code(403);
    exit('Invalid path');
}

// 根据扩展名设置 Content-Type
$ext = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
$mimeTypes = [
    'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'png' => 'image/png',
    'gif' => 'image/gif', 'webp' => 'image/webp', 'svg' => 'image/svg+xml',
    'txt' => 'text/plain', 'html' => 'text/html', 'css' => 'text/css',
    'js' => 'application/javascript', 'pdf' => 'application/pdf',
    'mp4' => 'video/mp4', 'mp3' => 'audio/mpeg',
];
$contentType = $mimeTypes[$ext] ?? 'application/octet-stream';

// 发送正确的响应头(确保在此之前没有任何输出)
header('Content-Type: ' . $contentType);
header('Content-Disposition: inline; filename="' . rawurlencode(basename($filePath)) . '"');
header('Cache-Control: public, max-age=86400');

// 从 WebDAV 获取并输出文件
$url = WEBDAV_URL . '/' . ltrim($filePath, '/');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, WEBDAV_USER . ':' . WEBDAV_PASS);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
curl_close($ch);


如Infinityfree这种虚拟主机也是可以正常使用的

如果分享的文件是图片
屏幕截图 2026-03-23 105337.png   
如果是txt 会直接显示
其它格式会直接下载

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
Xinsy + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

ahyaqi 发表于 2026-3-23 16:52
代码详细,感谢大神分享
anigm 发表于 2026-3-24 09:56
uchihaitchi 发表于 2026-5-30 09:09
 楼主| ChiZhu 发表于 2026-5-31 15:16

https://wwbkk.lanzoub.com/b007uhjb0b
密码  1111
梦奈宝塔的是用于nginx的虚拟主机的webdav管理
另外一个是用于Apache的虚拟主机的webdav管理
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-7-17 09:12

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表