吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3846|回复: 33
收起左侧

[其他原创] 使用html单个文件连接管理webdav(html源码) 修复

  [复制链接]
暗夜硝烟 发表于 2025-3-5 20:26
本帖最后由 暗夜硝烟 于 2025-3-24 10:39 编辑

本来想弄一个网页办的webdav文件管理客户端,目的是为了使用起来简单一点。
能力有限只能弄成这样了,发出来大家一起玩哈,有兴趣可以修改哈。

把代码复制到文本文档中,后缀改成html,浏览器打开就是下图的样子!

webdav.png

这是使用aardio制作的exe
https://wwvl.lanzout.com/i3DJi2rgytih
密码:53bx

这是单独的html文件
https://wwvl.lanzout.com/ijFeu2rgyyrg



[HTML] 纯文本查看 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>WebDAV文件管理器</title>
    <link rel="shortcut icon" href="logo.ico" type="image/x-icon">
    <style>
        /* 面包屑导航样式 */
        .breadcrumb {
            padding: 8px 15px;
            margin-bottom: 15px;
            background: #f5f5f5;
            border-radius: 4px;
            font-size: 18px;
        }
        h1 {
            margin-top: 5px; /* 上边距,可根据需求修改 */
            margin-bottom: 5px; /* 下边距,可根据需求修改 */
        }
        .breadcrumb a {
            color: #007bff;
            text-decoration: none;
            cursor: pointer;
            font-weight: bold;
        }
        .breadcrumb a:hover {
            text-decoration: none;
        }
        .breadcrumb span:last-child {
            color: #6c757d;
        }

        /* 文件列表表格样式 */
        .file-list {
            border: 1px solid #dee2e6;
            border-radius: 4px;
            overflow: hidden;
            margin-bottom: 100px; /* 为进度条留出空间 */
        }
        .file-header {
            display: flex;
            padding: 8px 15px;
            background: #f8f9fa;
            border-bottom: 2px solid #dee2e6;
            font-weight: 500;
        }
        .file-item {
            display: flex;
            padding: 8px 15px;
            border-bottom: 1px solid #dee2e6;
            align-items: center;
            cursor: pointer;
            transition: background 0.2s;
        }
        .file-item.selected {
            background-color: #e9f5ff;
            border-left: 3px solid #007bff;
        }
        .file-item:hover {
            background-color: #f8f9fa;
        }
        .file-name {
            flex: 0 1 40%;
            min-width: 200px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            padding-right: 15px;
        }
        .file-size {
            flex: 0 1 15%;
            min-width: 100px;
            color: #6c757d;
        }
        .file-modified {
            flex: 0 1 25%;
            min-width: 160px;
            color: #6c757d;
        }
        .file-actions {
            flex: 0 0 200px;
            text-align: right;
            padding-left: 15px;
        }

        /* 按钮样式 */
        button {
            padding: 5px 15px;
            color: white;
            border: none;
            border-radius: 3px;
            cursor: pointer;
            margin: 0 2px;
            transition: opacity 0.2s;
        }
        button:hover {
            opacity: 0.9;
        }
        button.primary {
            background: #007bff;
        }
        button.secondary {
            background: #6c757d;
        }
        button.success {
            background: #28a745;
        }
        button.danger {
            background: #dc3545;
        }
        button:disabled {
            background: #cccccc;
            cursor: not-allowed;
        }

        /* 弹窗样式 */
        .modal {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            padding: 20px;
            border-radius: 5px;
            box-shadow: 0 0 15px rgba(0,0,0,0.2);
            z-index: 1000;
        }
        .modal input {
            padding: 8px;
            margin: 10px 0;
            width: 300px;
            display: block;
        }
        #serverUrl {
            width: 96%; /* 修改地址输入框宽度为 300px */
        }
        .modal-buttons {
            margin-top: 15px;
            text-align: right;
        }

        /* 进度条样式 */
        .progress-container {
            position: fixed;
            bottom: 0; /* 使容器紧贴页面底部 */
            left: 0; /* 从页面最左边开始 */
            right: 0; /* 延伸到页面最右边 */
            width: 100%; /* 宽度为页面宽度 */
            padding: 15px;
            background: white;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            border-radius: 0; /* 因为宽度为 100%,可去掉圆角 */
            max-height: 60vh;
            overflow-y: auto;
        }
        .progress-item {
            margin: 8px 0;
        }
        .progress-bar {
            height: 12px;
            background: #f0f0f0;
            border-radius: 6px;
            overflow: hidden;
        }
        .progress-fill {
            width: 0%;
            height: 100%;
            background: #007bff;
            transition: width 0.3s ease;
        }
        .progress-text {
            font-size: 12px;
            color: #666;
            margin-top: 4px;
            display: flex;
            justify-content: space-between;
        }
        .upload-progress .progress-fill {
            background: #28a745;
        }

        /* 基础样式 */
        #loading { 
            display: none; 
            color: #666; 
            margin: 10px; 
        }
        .error { 
            color: red; 
            margin-left: 10px;
        }
        input[type="text"], input[type="password"] {
            padding: 8px;
            margin: 5px;
            border: 1px solid #ddd;
            border-radius: 4px;
            width: 200px;
        }
        input[type="text"]#serverUrl,
        input[type="text"]#username,
        input[type="password"]#password {
            display: inline-block; /* 显示inline-block 隐藏none*/
        }
    </style>
</head>
<body>
    <h1>WebDAV文件管理器</h1>

    <!-- 操作栏 -->
    <div>
        <input type="text" id="serverUrl" placeholder="服务器地址"> <br>    
        <input type="text" id="username" placeholder="用户名">
        <input type="password" id="password" placeholder="密码">
        <button class="primary">连接</button>
        <input type="file" id="fileInput" style="display:none" multiple>
        <button class="success">新建文件夹</button>
        <button class="secondary">上传文件</button>
        <button class="secondary" id="renameBtn" disabled>重命名</button>
        <button class="danger" id="deleteBtn" disabled>删除</button>
        <button class="secondary">刷新</button>
        <span id="loading">加载中...</span>
        <span class="error" id="errorMsg"></span>
    </div>

    <!-- 弹窗 -->
    <div id="renameModal" class="modal">
        <input type="text" id="newName" placeholder="输入新名称">
        <div class="modal-buttons">
            <button class="success">确认</button>
            <button class="secondary">取消</button>
        </div>
    </div>

    <div id="createFolderModal" class="modal">
        <input type="text" id="folderName" placeholder="输入文件夹名称">
        <div class="modal-buttons">
            <button class="success">创建</button>
            <button class="secondary">取消</button>
        </div>
    </div>

    <!-- 文件列表容器 -->
    <div id="fileList" style="margin-top:20px"></div>

    <!-- 进度容器 -->
    <div class="progress-container" id="progressContainer"></div>

    <script>
        // 配置信息
        const builtInServerUrl = '';  // 留空使用用户输入 输入后自动连接
        const builtInUsername = '';   // 留空使用用户输入
        const builtInPassword = '';   // 留空使用用户输入

        // 全局状态
        let currentAuth = '';
        let webdavRootUrl = '';
        let currentPath = '';
        let selectedItem = null;
        const activeTransfers = new Map();
        const folderCache = new Map(); // 新增:文件夹数据缓存
        let isNavigating = false; // 防止重复双击

        // 新增:保存表单数据到localStorage
        function saveFormData() {
            const formData = {
                serverUrl: document.getElementById('serverUrl').value,
                username: document.getElementById('username').value,
                password: document.getElementById('password').value
            };
            localStorage.setItem('webdavFormData', JSON.stringify(formData));
        }

        // 新增:加载保存的表单数据
        function loadFormData() {
            const savedData = localStorage.getItem('webdavFormData');
            if (savedData) {
                try {
                    const formData = JSON.parse(savedData);
                    document.getElementById('serverUrl').value = formData.serverUrl || '';
                    document.getElementById('username').value = formData.username || '';
                    document.getElementById('password').value = formData.password || '';
                } catch (e) {
                    console.error('加载保存的数据失败:', e);
                }
            }
        }

        // 修改后的connect函数
        async function connect() {
            const serverInput = document.getElementById('serverUrl').value || builtInServerUrl;
            const username = document.getElementById('username').value || builtInUsername;
            const password = document.getElementById('password').value || builtInPassword;

            try {
                // 处理可能的URL格式问题
                if (!serverInput.startsWith('http://') && !serverInput.startsWith('https://')) {
                    throw new Error('服务器地址必须以http://或https://开头');
                }
                webdavRootUrl = new URL(serverInput).href;
            } catch (e) {
                showError(`服务器地址无效: ${e.message}`);
                return;
            }

            currentAuth = btoa(`${username}:${password}`);

            try {
                await fetchDirectory(webdavRootUrl);
                // 点击连接时保存输入信息
                saveFormData();
            } catch (e) {
                showError(`连接失败: ${e.message}`);
            }
        }

        // 核心功能函数(修复路径处理)
        async function fetchDirectory(path) {
            if (!path.endsWith('/')) path += '/';

            if (folderCache.has(path)) { // 检查缓存
                const items = folderCache.get(path);
                renderFileList(items, path);
                return;
            }

            document.getElementById('loading').style.display = 'inline';
            try {
                const response = await fetch(path, {
                    method: 'PROPFIND',
                    headers: {
                        'Authorization': `Basic ${currentAuth}`,
                        'Depth': '1',
                        'Content-Type': 'text/xml; charset=utf-8'
                    },
                    body: `<?xml version="1.0"?>
                        <d:propfind xmlns:d="DAV:">
                            <d:prop>
                                <d:displayname/>
                                <d:getcontentlength/>
                                <d:getlastmodified/>
                                <d:resourcetype/>
                            </d:prop>
                        </d:propfind>`
                });

                if (!response.ok) throw new Error(`HTTP ${response.status}`);

                const data = await response.text();
                const items = parseResponse(data, path)
                   .filter(item => item.href !== path && !item.href.endsWith('.DS_Store/'));

                folderCache.set(path, items); // 缓存数据
                renderFileList(items, path);
            } catch (e) {
                showError(`操作失败: ${e.message}`);
            } finally {
                document.getElementById('loading').style.display = 'none';
            }
        }

        function parseResponse(xmlText, baseUrl) {
            const parser = new DOMParser();
            const doc = parser.parseFromString(xmlText, "text/xml");
            return Array.from(doc.getElementsByTagNameNS('DAV:', 'response')).map(item => {
                const href = item.getElementsByTagNameNS('DAV:', 'href')[0].textContent;
                const fullHref = new URL(href, baseUrl).href;
                const isDir = item.getElementsByTagNameNS('DAV:', 'collection').length > 0;

                const propStat = item.getElementsByTagNameNS('DAV:', 'propstat')[0];
                const props = propStat.getElementsByTagNameNS('DAV:', 'prop')[0];

                const pathname = new URL(fullHref).pathname;
                const cleanPath = decodeURIComponent(pathname).replace(/\/$/, '');
                const fileName = cleanPath.split('/').pop() || '';

                return {
                    href: fullHref,
                    name: fileName,
                    type: isDir ? 'directory' : 'file',
                    size: props.getElementsByTagNameNS('DAV:', 'getcontentlength')[0]?.textContent || null,
                    modified: props.getElementsByTagNameNS('DAV:', 'getlastmodified')[0]?.textContent || null
                };
            });
        }

        // 界面渲染
        function renderFileList(items, path) {
            currentPath = path;
            const container = document.getElementById('fileList');

            container.innerHTML = `
                <div class="file-list">
                    ${generateBreadcrumb(path)}
                    <div class="file-header">
                        <div class="file-name">名称</div>
                        <div class="file-size">大小</div>
                        <div class="file-modified">修改时间</div>
                        <div class="file-actions">操作</div>
                    </div>
                    ${items.map(item => `
                        <div class="file-item ${selectedItem === item.href ? 'selected' : ''}" 
                            
                             ${item.type === 'directory' ? `onmouseover="preloadDirectory('${item.href}')"` : ''}>
                            <div class="file-name" ${item.type === 'directory' ? `ondblclick="enterDirectory('${item.href}')"` : ''}>
                                ${item.type === 'directory' ? '&#128193;' : '&#128196;'} 
                                ${item.name}
                            </div>
                            <div class="file-size">${formatSize(item.size)}</div>
                            <div class="file-modified">${formatDate(item.modified)}</div>
                            <div class="file-actions">
                                ${item.type === 'file' ? 
                                    `<button class="secondary">下载</button>` : ''}
                            </div>
                        </div>
                    `).join('')}
                    ${items.length === 0 ? `
                        <div class="file-item" style="justify-content:center; color:#6c757d;">
                            空目录
                        </div>
                    ` : ''}
                </div>
            `;

            document.getElementById('renameBtn').disabled = !selectedItem;
            document.getElementById('deleteBtn').disabled = !selectedItem;
        }

        function toggleSelection(href) {
            selectedItem = selectedItem === href ? null : href;
            fetchDirectory(currentPath);
        }

        function generateBreadcrumb(path) {
            const base = new URL(webdavRootUrl);
            // 规范化基础路径:解码、确保以斜杠结尾
            const basePath = decodeURIComponent(base.pathname).replace(/\/?$/, '/');
            // 处理当前路径
            const current = new URL(path);
            const currentPathname = decodeURIComponent(current.pathname).replace(/\/?$/, '/');

            // 获取相对路径部分
            const relativePath = currentPathname.slice(basePath.length);
            const segments = relativePath.split('/').filter(Boolean);

            return `<div class="breadcrumb">
                <a>&#127968;主页</a>
                ${segments.length > 0 ? ' / ' : ''}
                ${segments.map((seg, i) => {
                    const urlSegments = segments.slice(0, i+1);
                    const url = new URL(basePath + urlSegments.join('/') + '/', base.href);
                    return i === segments.length-1 ? 
                        `<span>${decodeURIComponent(seg)}</span>` : 
                        `<a>${decodeURIComponent(seg)}</a> / `;
                }).join('')}
            </div>`;
        }

        // 工具函数
        function formatSize(bytes) {
            if (!bytes) return '-';
            const units = ['B', 'KB', 'MB', 'GB'];
            let size = parseFloat(bytes);
            for (let unit of units) {
                if (size < 1024) return `${size.toFixed(1)} ${unit}`;
                size /= 1024;
            }
            return `${size.toFixed(1)} GB`;
        }

        function formatDate(dateStr) {
            try {
                return new Date(dateStr).toLocaleString('zh-CN');
            } catch {
                return dateStr;
            }
        }

        function showError(message) {
            document.getElementById('errorMsg').textContent = message;
            setTimeout(() => document.getElementById('errorMsg').textContent = '', 3000);
        }

        // 核心操作
        async function connect() {
            const server = document.getElementById('serverUrl').value || builtInServerUrl;
            const username = document.getElementById('username').value || builtInUsername;
            const password = document.getElementById('password').value || builtInPassword;

            currentAuth = btoa(`${username}:${password}`);
            webdavRootUrl = new URL(server).href;

            try {
                await fetchDirectory(webdavRootUrl);
                // 点击连接时保存输入信息
                saveFormData();
            } catch (e) {
                showError(`连接失败: ${e.message}`);
            }
        }

        async function enterDirectory(path) {
            if (isNavigating) return;
            if (!path.endsWith('/')) path += '/';
            try {
                isNavigating = true;
                document.getElementById('loading').style.display = 'inline';
                selectedItem = null;
                await fetchDirectory(path);
                document.getElementById('fileList').scrollIntoView({ behavior: 'smooth' });
            } catch (e) {
                showError(`进入目录失败: ${e.message}`);
            } finally {
                isNavigating = false;
                document.getElementById('loading').style.display = 'none';
            }
        }

        // 新增:预加载文件夹数据
        async function preloadDirectory(path) {
            if (!path.endsWith('/')) path += '/';
            if (!folderCache.has(path)) {
                try {
                    const response = await fetch(path, {
                        method: 'PROPFIND',
                        headers: {
                            'Authorization': `Basic ${currentAuth}`,
                            'Depth': '1',
                            'Content-Type': 'text/xml; charset=utf-8'
                        },
                        body: `<?xml version="1.0"?>
                            <d:propfind xmlns:d="DAV:">
                                <d:prop>
                                    <d:displayname/>
                                    <d:getcontentlength/>
                                    <d:getlastmodified/>
                                    <d:resourcetype/>
                                </d:prop>
                            </d:propfind>`
                    });

                    if (!response.ok) throw new Error(`HTTP ${response.status}`);

                    const data = await response.text();
                    const items = parseResponse(data, path)
                       .filter(item => item.href !== path && !item.href.endsWith('.DS_Store/'));

                    folderCache.set(path, items);
                } catch (e) {
                    console.error(`预加载失败: ${e.message}`);
                }
            }
        }

        // 文件操作
        async function deleteItem() {
            if (!selectedItem || !confirm('确定要永久删除此项目吗?')) return;

            try {
                const response = await fetch(selectedItem, {
                    method: 'DELETE',
                    headers: { 'Authorization': `Basic ${currentAuth}` }
                });
                if (!response.ok) throw new Error(`HTTP ${response.status}`);
                selectedItem = null;
                folderCache.delete(currentPath); // 删除缓存
                await fetchDirectory(currentPath);
            } catch (e) {
                showError(`删除失败: ${e.message}`);
            }
        }

        function showRenameModal() {
            if (!selectedItem) return;
            document.getElementById('newName').value = decodeURIComponent(
                selectedItem.split('/').pop().replace(/%20/g, ' ')
            );
            document.getElementById('renameModal').style.display = 'block';
        }

        async function confirmRename() {
            if (!selectedItem) return;
            const newName = encodeURIComponent(document.getElementById('newName').value);
            const oldUrl = new URL(selectedItem);
            const newUrl = new URL(newName, oldUrl).href;

            try {
                const response = await fetch(selectedItem, {
                    method: 'MOVE',
                    headers: {
                        'Authorization': `Basic ${currentAuth}`,
                        'Destination': newUrl,
                        'Overwrite': 'F'
                    }
                });
                if (!response.ok) throw new Error(`HTTP ${response.status}`);
                selectedItem = null;
                folderCache.delete(currentPath); // 删除缓存
                await fetchDirectory(currentPath);
                closeModal();
            } catch (e) {
                showError(`重命名失败: ${e.message}`);
            }
        }

        function showCreateFolderModal() {
            document.getElementById('createFolderModal').style.display = 'block';
        }

        async function confirmCreateFolder() {
            const folderName = encodeURIComponent(document.getElementById('folderName').value);
            const newUrl = new URL(folderName + '/', currentPath).href;

            try {
                const response = await fetch(newUrl, {
                    method: 'MKCOL',
                    headers: { 'Authorization': `Basic ${currentAuth}` }
                });
                if (!response.ok) throw new Error(`HTTP ${response.status}`);
                folderCache.delete(currentPath); // 删除缓存
                await fetchDirectory(currentPath);
                closeModal();
            } catch (e) {
                showError(`创建失败: ${e.message}`);
            }
        }

        // 上传下载功能
        document.getElementById('fileInput').addEventListener('change', function(e) {
            const files = Array.from(e.target.files);
            if (files.length === 0) return;

            files.forEach(file => {
                uploadFile(file);
            });
        });

        function uploadFile(file) {
            const uploadId = `upload-${Date.now()}`;
            const url = new URL(encodeURIComponent(file.name), currentPath).href;

            // 创建进度元素
            const progressElement = document.createElement('div');
            progressElement.className = 'progress-item upload-progress';
            progressElement.innerHTML = `
                <div class="progress-info">
                    <span>${file.name}</span>
                    <span class="progress-text">0%</span>
                </div>
                <div class="progress-bar">
                    <div class="progress-fill" id="fill-${uploadId}"></div>
                </div>
            `;
            document.getElementById('progressContainer').appendChild(progressElement);

            const xhr = new XMLHttpRequest();
            xhr.open('PUT', url);
            xhr.setRequestHeader('Authorization', `Basic ${currentAuth}`);
            xhr.setRequestHeader('Content-Type', 'application/octet-stream');

            xhr.upload.onprogress = function(e) {
                if (e.lengthComputable) {
                    const percent = Math.round((e.loaded / e.total) * 100);
                    updateProgress(uploadId, percent);
                }
            };

            xhr.onload = function() {
                if (xhr.status === 201 || xhr.status === 200) {
                    folderCache.delete(currentPath); // 删除缓存
                    fetchDirectory(currentPath);
                    removeProgress(uploadId);
                }
            };

            xhr.onerror = function() {
                showError(`上传失败: ${xhr.statusText}`);
                removeProgress(uploadId);
            };

            activeTransfers.set(uploadId, xhr);
            xhr.send(file);
        }

        function downloadFile(url) {
            const downloadId = `download-${Date.now()}`;
            const fileName = decodeURIComponent(url.split('/').pop());
            // 新增刷新功能函数
            function refreshCurrentDirectory() {
                if (!currentAuth) {
                    showError('请先连接到服务器');
                    return;
                }
                if (!currentPath) {
                    showError('当前路径不可用');
                    return;
                }
                // 清除选中状态并刷新
                selectedItem = null;
                fetchDirectory(currentPath);
            }

            // 创建进度元素
            const progressElement = document.createElement('div');
            progressElement.className = 'progress-item';
            progressElement.innerHTML = `
                <div class="progress-info">
                    <span>${fileName}</span>
                    <span class="progress-text">0%</span>
                </div>
                <div class="progress-bar">
                    <div class="progress-fill" id="fill-${downloadId}"></div>
                </div>
            `;
            document.getElementById('progressContainer').appendChild(progressElement);

            const xhr = new XMLHttpRequest();
            xhr.open('GET', url);
            xhr.setRequestHeader('Authorization', `Basic ${currentAuth}`);
            xhr.responseType = 'blob';

            xhr.onprogress = function(e) {
                if (e.lengthComputable) {
                    const percent = Math.round((e.loaded / e.total) * 100);
                    updateProgress(downloadId, percent);
                }
            };

            xhr.onload = function() {
                if (xhr.status === 200) {
                    const blob = xhr.response;
                    const link = document.createElement('a');
                    link.href = URL.createObjectURL(blob);
                    link.download = fileName;
                    link.click();
                    URL.revokeObjectURL(link.href);
                    removeProgress(downloadId);
                }
            };

            xhr.onerror = function() {
                showError(`下载失败: ${xhr.statusText}`);
                removeProgress(downloadId);
            };

            activeTransfers.set(downloadId, xhr);
            xhr.send();
        }

        function updateProgress(id, percent) {
            const fill = document.getElementById(`fill-${id}`);
            const text = fill?.parentElement?.previousElementSibling?.querySelector('.progress-text');
            if (fill) fill.style.width = `${percent}%`;
            if (text) text.textContent = `${percent}%`;
        }

        function removeProgress(id) {
            const element = document.querySelector(`#fill-${id}`)?.closest('.progress-item');
            if (element) element.remove();
            activeTransfers.delete(id);
        }

        // 通用函数
        function closeModal() {
            document.querySelectorAll('.modal').forEach(m => m.style.display = 'none');
            document.getElementById('folderName').value = '';
            document.getElementById('newName').value = '';
        }

        // 初始化(添加自动连接)
        window.onload = () => {
            loadFormData(); // 先加载保存的数据

            // 如果有内置配置,则覆盖对应字段
            if (builtInServerUrl) {
                document.getElementById('serverUrl').value = builtInServerUrl;
            }
            if (builtInUsername) {
                document.getElementById('username').value = builtInUsername;
            }
            if (builtInPassword) {
                document.getElementById('password').value = builtInPassword;
            }

            // 自动连接的逻辑
            const hasBuiltInConfig = builtInServerUrl || builtInUsername || builtInPassword;
            if (hasBuiltInConfig) {
                // 使用内置配置自动连接
                setTimeout(() => connect(), 500);
            } else {
                // 检查localStorage是否有数据
                const savedData = localStorage.getItem('webdavFormData');
                if (savedData) {
                    setTimeout(() => connect(), 500);
                }
            }
        };
    </script>
</body>
</html>    


免费评分

参与人数 17吾爱币 +23 热心值 +12 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
zephyrcn + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
femten + 1 + 1 谢谢@Thanks!
GMCN + 1 + 1 用心讨论,共获提升!
Carinx + 1 + 1 用心讨论,共获提升!
liqiang9 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
jiukou + 1 + 1 谢谢@Thanks!
中之易 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
aigc + 1 热心回复!
gxsky + 1 + 1 我很赞同!
Hameel + 1 我很赞同!
Me祝 + 1 + 1 谢谢@Thanks!
yaoshun3 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
liushishi404 + 1 谢谢@Thanks!
tsyhome + 1 + 1 谢谢@Thanks!
aokesuper + 1 + 1 用心讨论,共获提升!
weidechan + 1 用心讨论,共获提升!

查看全部评分

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

janny82 发表于 2025-3-5 22:56
xzdiming 发表于 2025-3-5 22:09
https://s3.bmp.ovh/imgs/2025/03/05/7ad8e9761101fb23.jpg

你这应该是编码不对,右键 UF8编码就可以了
zhaoxiaoouyi 发表于 2025-3-5 20:27
ccmax 发表于 2025-3-5 20:35
tsyhome 发表于 2025-3-5 21:01
感谢楼主分享,喜欢这种可以直接使用的明码代码!
myconan 发表于 2025-3-5 21:21
感谢分享
liushishi404 发表于 2025-3-5 21:28
非常好的方案,感谢分享
xzdiming 发表于 2025-3-5 22:09
本帖最后由 xzdiming 于 2025-3-5 22:10 编辑

<img src = 'https://s3.bmp.ovh/imgs/2025/03/05/7ad8e9761101fb23.jpg' >

https://s3.bmp.ovh/imgs/2025/03/05/7ad8e9761101fb23.jpg 无标题.jpg
addtool 发表于 2025-3-5 22:47
感谢分享,看起来很不错
beatxiaoyuxy 发表于 2025-3-5 22:53
感谢分享,用下试试
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2026-9-16 00:01

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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