Chrome 通过FTP,HTTP 调用 Everything 浏览和搜刮本地文件系统

[复制链接]
发表于 2025-6-2 04:14:20 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
【提问1】

Chrome调用本地 everything.exe, everything 好像有本地 FTP 服务器?
【DeepSeek R1 回答】

是的,Everything 确实内置了 HTTP/FTP 服务器功能,这提供了一种相对安全的浏览器与本地应用交互的方式。以下是完整的实现方案:
通过 Everything 的 HTTP 服务器实现浏览器交互

Everything (v1.4+) 内置的 HTTP 服务器允许通过浏览器实行搜刮操纵:

  • 启用 Everything HTTP 服务器:

    • 打开 Everything → 工具 → 选项 → HTTP 服务器
    • 启用 HTTP 服务器(默认端口 8080)
    • 设置允许的访问权限(保举设置为 127.0.0.1 仅限本地访问)

  • HTML 页面通过 AJAX 调用 Everything:
  1. <!DOCTYPE html>
  2. <html>
  3. <body>
  4.   <input type="text" id="searchInput" placeholder="搜索文件...">
  5.   <button onclick="searchEverything()">搜索</button>
  6.   <div id="results"></div>
  7.   <script>
  8.   async function searchEverything() {
  9.     const query = document.getElementById('searchInput').value;
  10.     const response = await fetch(`http://localhost:8080/?search=${encodeURIComponent(query)}&json=1`);
  11.     const data = await response.json();
  12.    
  13.     let resultsHTML = "<h3>搜索结果:</h3><ul>";
  14.     data.results.forEach(file => {
  15.       resultsHTML += `<li><a href="file:///${file.path}" target="_blank">${file.name}</a></li>`;
  16.     });
  17.     resultsHTML += "</ul>";
  18.    
  19.     document.getElementById("results").innerHTML = resultsHTML;
  20.   }
  21.   </script>
  22. </body>
  23. </html>
复制代码
通过 Everything 的 FTP 服务器访问文件

Everything 也支持 FTP 服务器(需在设置中启用):
  1. // 在页面中生成 FTP 链接
  2. function generateFtpLink(path) {
  3.   return `ftp://localhost:21/${encodeURI(path)}`;
  4. }
  5. // 使用示例
  6. document.getElementById('ftpLink').href = generateFtpLink("C:/Users/MyFile.txt");
复制代码
进阶方案:通过 Native Messaging 深度集成

若必要实行更复杂的本地操纵(如启动程序),需创建浏览器扩展:

  • 创建扩展文件布局:
  1. everything-extension/
  2. ├── manifest.json
  3. ├── background.js
  4. ├── content.js
  5. └── native-host/
  6.     ├── everything-host.bat
  7.     └── everything-host.ps1
复制代码

  • manifest.json:
  1. {
  2.   "manifest_version": 3,
  3.   "name": "Everything 集成",
  4.   "version": "1.0",
  5.   "permissions": ["nativeMessaging"],
  6.   "background": {
  7.     "service_worker": "background.js"
  8.   },
  9.   "content_scripts": [{
  10.     "matches": ["http://localhost/*"],
  11.     "js": ["content.js"]
  12.   }]
  13. }
复制代码

  • 本地主机应用 (everything-host.ps1):
  1. while ($true) {
  2.   $input = [Console]::In.ReadLine()
  3.   $command = $input | ConvertFrom-Json
  4.   
  5.   # 执行 Everything 命令
  6.   if ($command.action -eq "launch") {
  7.     Start-Process "C:\Path\To\Everything.exe" -ArgumentList "-search", $command.query
  8.     [Console]::Out.WriteLine('{"status":"success"}')
  9.   }
  10. }
复制代码

  • 注册本地主机(注册表文件):
  1. Windows Registry Editor Version 5.00
  2. [HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.example.everything_host]
  3. @="C:\\path\\to\\everything-host-manifest.json"
复制代码

  • 扩展通信脚本:
  1. // content.js
  2. document.getElementById('launchBtn').addEventListener('click', () => {
  3.   chrome.runtime.sendNativeMessage('com.example.everything_host',
  4.     {action: "launch", query: "*.pdf"},
  5.     response => console.log(response)
  6.   );
  7. });
复制代码
安全注意事项


  • 限制 HTTP/FTP 服务器仅限本地访问(127.0.0.1)
  • 对用户输入进行严酷过滤,防止路径遍历攻击
  • 在扩展中利用最小权限原则
  • 避免通过 FTP 传输敏感文件
  • 全部本地主机脚本需进行代码签名
替换方案(无需 Everything)

若只需简单命令实行,可用 PowerShell 作为后端:
  1. // Node.js 服务器
  2. const express = require('express');
  3. const { exec } = require('child_process');
  4. const app = express();
  5. app.get('/run', (req, res) => {
  6.   const cmd = req.query.cmd;
  7.   exec(cmd, (error, stdout) => {
  8.     res.send(stdout || error.message);
  9.   });
  10. });
  11. app.listen(3000);
复制代码
然后在 HTML 中调用:
  1. fetch('http://localhost:3000/run?cmd=dir')
  2.   .then(response => response.text())
  3.   .then(data => console.log(data));
复制代码
总结:Everything 的 HTTP/FTP 服务器是最安全便捷的浏览器集成方案。对于必要深度系统集成的场景,Native Messaging 扩展方案虽然复杂但功能最强盛。普通用户保举利用 HTTP 服务器方案即可满足大部门需求。

【提问2】

通过 Everything 的 FTP 服务器访问文件,这能出一个详细解决方案吗?chrome 能利用everything 搜刮本地某目次里某文件吗
【DeepSeek R1 回答】

下面我将提供一个完整的详细解决方案,通过 Chrome 浏览器利用 Everything 的 FTP 服务器访问本地文件系统,并实现文件搜刮功能。
完整解决方案:Chrome + Everything FTP 服务器集成

第一部门:Everything 配置


  • 启用 Everything FTP 服务器

    • 打开 Everything → 工具 → 选项 → FTP 服务器
    • 勾选 “启用 FTP 服务器”
    • 配置设置:
      1. 服务器名称: MyLocalFTP
      2. 监听端口: 2121(避免使用 21 端口需要管理员权限)
      3. 绑定到: 127.0.0.1(仅限本地访问)
      4. 用户名: (留空表示匿名访问)
      5. 密码: (留空)
      6. 根目录: C:\(或您想要搜索的特定目录)
      复制代码
    • 生存设置

  • 验证 FTP 服务器

    • 打开文件资源管理器,输入 ftp://127.0.0.1:2121
    • 应该能看到本地文件列表

第二部门:HTML/JavaScript 实现

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>Everything FTP 文件搜索器</title>
  7.     <style>
  8.         body { font-family: 'Segoe UI', Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
  9.         .search-box { display: flex; margin-bottom: 20px; }
  10.         #searchInput { flex: 1; padding: 10px; font-size: 16px; border: 1px solid #ddd; }
  11.         #searchButton { padding: 10px 20px; background: #4285f4; color: white; border: none; cursor: pointer; }
  12.         #results { list-style: none; padding: 0; }
  13.         .file-item { padding: 10px; border-bottom: 1px solid #eee; }
  14.         .file-item:hover { background-color: #f9f9f9; }
  15.         .file-link { color: #1a73e8; text-decoration: none; }
  16.         .file-link:hover { text-decoration: underline; }
  17.         .file-info { font-size: 12px; color: #666; margin-top: 5px; }
  18.         .loading { display: none; text-align: center; padding: 20px; }
  19.     </style>
  20. </head>
  21. <body>
  22.     <h1>本地文件搜索器 (Everything FTP)</h1>
  23.     <div class="search-box">
  24.         <input type="text" id="searchInput" placeholder="输入文件名或扩展名 (如: *.pdf project.docx)">
  25.         <button id="searchButton">搜索</button>
  26.     </div>
  27.    
  28.     <div class="loading" id="loadingIndicator">
  29.         <p>正在搜索中... <span id="resultCount">0</span> 个结果</p>
  30.     </div>
  31.    
  32.     <ul id="results"></ul>
  33.     <script>
  34.         // Everything FTP 配置
  35.         const FTP_HOST = '127.0.0.1';
  36.         const FTP_PORT = 2121;
  37.         const FTP_URL = `ftp://${FTP_HOST}:${FTP_PORT}/`;
  38.         
  39.         // 搜索状态
  40.         let currentSearch = null;
  41.         let resultCount = 0;
  42.         
  43.         // DOM 元素
  44.         const searchInput = document.getElementById('searchInput');
  45.         const searchButton = document.getElementById('searchButton');
  46.         const resultsContainer = document.getElementById('results');
  47.         const loadingIndicator = document.getElementById('loadingIndicator');
  48.         const resultCountElement = document.getElementById('resultCount');
  49.         
  50.         // 初始化
  51.         document.addEventListener('DOMContentLoaded', () => {
  52.             searchButton.addEventListener('click', startSearch);
  53.             searchInput.addEventListener('keyup', (e) => {
  54.                 if (e.key === 'Enter') startSearch();
  55.             });
  56.         });
  57.         
  58.         // 开始搜索
  59.         function startSearch() {
  60.             const query = searchInput.value.trim();
  61.             if (!query) return;
  62.             
  63.             // 中止之前的搜索
  64.             if (currentSearch) {
  65.                 currentSearch.abort();
  66.             }
  67.             
  68.             // 重置结果
  69.             resultsContainer.innerHTML = '';
  70.             resultCount = 0;
  71.             resultCountElement.textContent = '0';
  72.             loadingIndicator.style.display = 'block';
  73.             
  74.             // 创建 Everything FTP 搜索 URL
  75.             const searchUrl = `${FTP_URL}?search=${encodeURIComponent(query)}`;
  76.             
  77.             // 创建 XMLHttpRequest 对象
  78.             currentSearch = new XMLHttpRequest();
  79.             currentSearch.open('GET', searchUrl, true);
  80.             
  81.             // 处理响应数据(流式处理)
  82.             let buffer = '';
  83.             currentSearch.onprogress = function(event) {
  84.                 const chunk = currentSearch.responseText.substring(buffer.length);
  85.                 buffer += chunk;
  86.                
  87.                 // 处理接收到的数据
  88.                 processFTPResponse(buffer);
  89.                 resultCountElement.textContent = resultCount;
  90.             };
  91.             
  92.             currentSearch.onload = function() {
  93.                 if (currentSearch.status === 200) {
  94.                     processFTPResponse(buffer);
  95.                     loadingIndicator.style.display = 'none';
  96.                 }
  97.             };
  98.             
  99.             currentSearch.onerror = function() {
  100.                 loadingIndicator.style.display = 'none';
  101.                 resultsContainer.innerHTML = '<li class="file-item">连接FTP服务器失败。请确保Everything正在运行且FTP服务器已启用。</li>';
  102.             };
  103.             
  104.             currentSearch.send();
  105.         }
  106.         
  107.         // 处理FTP响应数据
  108.         function processFTPResponse(data) {
  109.             // 简单解析FTP列表格式
  110.             const lines = data.split('\r\n');
  111.             for (const line of lines) {
  112.                 if (!line.trim()) continue;
  113.                
  114.                 // 解析文件信息(简化版,实际需要更复杂的解析)
  115.                 const parts = line.split(/\s+/);
  116.                 if (parts.length < 9) continue;
  117.                
  118.                 const permissions = parts[0];
  119.                 const isDirectory = permissions[0] === 'd';
  120.                 const size = parts[4];
  121.                 const date = `${parts[5]} ${parts[6]} ${parts[7]}`;
  122.                 const filename = parts.slice(8).join(' ');
  123.                 const fullPath = filename;
  124.                
  125.                 // 只显示文件(过滤目录)
  126.                 if (!isDirectory) {
  127.                     addFileResult(fullPath, size, date);
  128.                 }
  129.             }
  130.         }
  131.         
  132.         // 添加文件到结果列表
  133.         function addFileResult(path, size, modifiedDate) {
  134.             resultCount++;
  135.             
  136.             // 提取文件名和扩展名
  137.             const filename = path.split('/').pop() || path;
  138.             const extension = filename.split('.').pop() || '';
  139.             
  140.             // 创建文件链接
  141.             const fileUrl = `${FTP_URL}${encodeURI(path)}`;
  142.             
  143.             const listItem = document.createElement('li');
  144.             listItem.className = 'file-item';
  145.             listItem.innerHTML = `
  146.                 <a href="${fileUrl}" class="file-link" download="${filename}">${filename}</a>
  147.                 <div class="file-info">
  148.                     大小: ${formatFileSize(size)} |
  149.                     修改日期: ${modifiedDate} |
  150.                     类型: ${extension.toUpperCase()} 文件
  151.                 </div>
  152.             `;
  153.             
  154.             resultsContainer.appendChild(listItem);
  155.         }
  156.         
  157.         // 格式化文件大小
  158.         function formatFileSize(bytes) {
  159.             if (bytes < 1024) return bytes + ' B';
  160.             if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB';
  161.             return (bytes / 1048576).toFixed(1) + ' MB';
  162.         }
  163.     </script>
  164. </body>
  165. </html>
复制代码
第三部门:利用说明


  • 准备工作:

    • 确保 Everything 正在运行且 FTP 服务器已启用
    • 在 Chrome 中打开此 HTML 文件(直接双击或通过 file:// 路径打开)

  • 搜刮功能:

    • 在搜刮框输入查询:

      • 利用 Everything 搜刮语法:*.pdf、project.docx、*.jpg width:1920 height:1080
      • 支持布尔运算符:AND、OR、NOT

    • 点击搜刮或按 Enter 键
    • 结果将实时加载显示

  • 文件操纵:

    • 点击文件名将下载该文件
    • 鼠标悬停在文件项上可查看详细信息

第四部门:安全增强配置

由于直接利用 FTP 存在安全风险,建议添加以下安全措施:

  • Everything 设置:
    1. ; Everything.ini 安全配置
    2. ftp_server_allow_anonymous=0
    3. ftp_server_username=chrome_user
    4. ftp_server_password=secure_password123
    5. ftp_server_root_path=C:\Users\Public\Share
    6. ftp_server_passive_mode=1
    复制代码
  • HTML 身份验证:
    1. // 在搜索URL中添加凭据
    2. const FTP_AUTH = 'chrome_user:secure_password123';
    3. const searchUrl = `ftp://${FTP_AUTH}@${FTP_HOST}:${FTP_PORT}/?search=${query}`;
    复制代码
  • 限制文件类型:
    1. // 在 addFileResult 函数中添加
    2. const allowedExtensions = ['pdf', 'docx', 'jpg', 'png'];
    3. if (!allowedExtensions.includes(extension.toLowerCase())) return;
    复制代码
第五部门:替换方案(保举)

由于当代浏览器对 FTP 支持有限(Chrome 88+ 已禁用 FTP),保举利用 Everything 的 HTTP 服务器方案:
  1. // 使用 HTTP 服务器替代 FTP
  2. const HTTP_EVERYTHING_URL = 'http://localhost:8080/';
  3. async function searchEverything() {
  4.     const response = await fetch(`${HTTP_EVERYTHING_URL}?search=${query}&json=1`);
  5.     const data = await response.json();
  6.    
  7.     data.results.forEach(file => {
  8.         // 创建本地文件链接
  9.         const fileUrl = `file:///${file.path.replace(/\\/g, '/')}`;
  10.         addFileResult(file.path, file.size, file.date_modified);
  11.     });
  12. }
复制代码
注意事项


  • 浏览器限制:

    • Chrome 88+ 默认禁用 FTP 支持
    • 文件下载大概被浏览器安全计谋制止
    • 本地文件访问必要用户授权

  • 安全告诫:

    • 仅在受信任的情况中利用
    • 不要将 FTP 服务器袒露在公共网络
    • 设置强暗码或利用 HTTP 服务器替换

  • 性能优化:

    • 限制返回结果数量(在 URL 中添加 &offset=0&count=100)
    • 添加防抖机制避免频仍搜刮
    • 利用 Web Workers 处置处罚大型结果集

  • 跨平台支持:

    • Windows:完整支持
    • macOS/Linux:必要 Wine 或 CrossOver 运行 Everything

这个解决方案让您可以直接在 Chrome 浏览器中利用 Everything 的强盛搜刮功能访问本地文件系统,同时通过 FTP 服务器提供文件访问功能。对于当代浏览器,建议优先利用 Everything 的 HTTP 服务器方案以得到更好的兼容性。

【提问3】

通过 Everything 的 HTTP 服务器访问文件,这能出一个详细解决方案吗?chrome 能利用everything 搜刮本地某目次里某文件吗
【DeepSeek R1 回答】

Everything HTTP 服务器集成解决方案

下面我将提供一个完整的解决方案,通过 Chrome 浏览器利用 Everything 的 HTTP 服务器实现本地文件搜刮和访问功能。
团体思路


  • 配置 Everything 的 HTTP 服务器
  • 创建 HTML 页面调用 Everything API
  • 实现搜刮功能和结果展示
  • 提供文件预览和下载功能
完整解决方案

[code]<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Everything 本地文件搜索器</title>
    <style>
        :root {
            --primary-color: #4285f4;
            --secondary-color: #34a853;
            --background-color: #f8f9fa;
            --card-color: #ffffff;
            --text-color: #202124;
            --border-color: #dadce0;
        }
        
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        
        body {
            font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
            background-color: var(--background-color);
            color: var(--text-color);
            line-height: 1.6;
            padding: 20px;
            max-width: 1200px;
            margin: 0 auto;
        }
        
        header {
            text-align: center;
            margin-bottom: 30px;
            padding: 20px 0;
            border-bottom: 1px solid var(--border-color);
        }
        
        h1 {
            color: var(--primary-color);
            font-size: 2.5rem;
            margin-bottom: 10px;
        }
        
        .subtitle {
            color: #5f6368;
            font-size: 1.1rem;
            max-width: 700px;
            margin: 0 auto;
        }
        
        .search-container {
            background-color: var(--card-color);
            border-radius: 8px;
            box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
            padding: 25px;
            margin-bottom: 30px;
        }
        
        .search-box {
            display: flex;
            gap: 10px;
            margin-bottom: 20px;
        }
        
        #searchInput {
            flex: 1;
            padding: 15px;
            font-size: 16px;
            border: 1px solid var(--border-color);
            border-radius: 4px;
            transition: border-color 0.3s;
        }
        
        #searchInput:focus {
            outline: none;
            border-color: var(--primary-color);
            box-shadow: 0 0 0 2px rgba(66, 133, 244, 0.2);
        }
        
        #searchButton {
            padding: 15px 25px;
            background-color: var(--primary-color);
            color: white;
            border: none;
            border-radius: 4px;
            font-size: 16px;
            cursor: pointer;
            transition: background-color 0.3s;
        }
        
        #searchButton:hover {
            background-color: #3367d6;
        }
        
        .filters {
            display: flex;
            gap: 15px;
            flex-wrap: wrap;
            margin-bottom: 20px;
        }
        
        .filter-group {
            flex: 1;
            min-width: 200px;
        }
        
        .filter-group label {
            display: block;
            margin-bottom: 5px;
            font-weight: 500;
        }
        
        .filter-group select, .filter-group input {
            width: 100%;
            padding: 10px;
            border: 1px solid var(--border-color);
            border-radius: 4px;
        }
        
        .results-container {
            background-color: var(--card-color);
            border-radius: 8px;
            box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
            overflow: hidden;
        }
        
        .results-header {
            padding: 15px 20px;
            background-color: #f5f5f5;
            border-bottom: 1px solid var(--border-color);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        
        #resultCount {
            font-weight: 500;
        }
        
        #results {
            max-height: 500px;
            overflow-y: auto;
        }
        
        .result-item {
            padding: 15px 20px;
            border-bottom: 1px solid var(--border-color);
            display: flex;
            align-items: center;
        }
        
        .result-item:hover {
            background-color: #f8f9fa;
        }
        
        .file-icon {
            width: 32px;
            height: 32px;
            margin-right: 15px;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #5f6368;
        }
        
        .file-icon img {
            max-width: 100%;
            max-height: 100%;
        }
        
        .file-info {
            flex: 1;
            min-width: 0;
        }
        
        .file-name {
            font-weight: 500;
            margin-bottom: 5px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        
        .file-details {
            display: flex;
            gap: 15px;
            font-size: 0.85rem;
            color: #5f6368;
        }
        
        .file-actions {
            display: flex;
            gap: 10px;
        }
        
        .action-btn {
            padding: 8px 12px;
            background-color: #f1f3f4;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background-color 0.3s;
        }
        
        .action-btn:hover {
            background-color: #e8eaed;
        }
        
        .preview-btn {
            background-color: #f8f9fa;
            color: var(--primary-color);
        }
        
        .download-btn {
            background-color: var(--secondary-color);
            color: white;
        }
        
        .loading-container {
            display: none;
            text-align: center;
            padding: 40px;
        }
        
        .loading-spinner {
            border: 4px solid rgba(0, 0, 0, 0.1);
            border-top: 4px solid var(--primary-color);
            border-radius: 50%;
            width: 40px;
            height: 40px;
            animation: spin 1s linear infinite;
            margin: 0 auto 20px;
        }
        
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        
        .no-results {
            text-align: center;
            padding: 40px;
            color: #5f6368;
        }
        
        .error-message {
            background-color: #fce8e6;
            color: #d93025;
            padding: 15px;
            border-radius: 4px;
            margin-top: 20px;
            display: none;
        }
        
        .preview-container {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0,0,0,0.8);
            z-index: 1000;
            padding: 20px;
        }
        
        .preview-content {
            background-color: white;
            border-radius: 8px;
            max-width: 900px;
            max-height: 90vh;
            margin: 20px auto;
            overflow: auto;
            position: relative;
        }
        
        .preview-header {
            padding: 15px 20px;
            background-color: #f5f5f5;
            display: flex;
            justify-content: space-between;
            align-items: center;
            position: sticky;
            top: 0;
            z-index: 10;
        }
        
        .close-preview {
            background: none;
            border: none;
            font-size: 1.5rem;
            cursor: pointer;
            color: #5f6368;
        }
        
        .preview-body {
            padding: 20px;
        }
        
        .preview-body img, .preview-body video {
            max-width: 100%;
            display: block;
            margin: 0 auto;
        }
        
        .preview-body audio {
            width: 100%;
        }
        
        footer {
            text-align: center;
            margin-top: 40px;
            padding: 20px 0;
            color: #5f6368;
            font-size: 0.9rem;
            border-top: 1px solid var(--border-color);
        }
        
        @media (max-width: 768px) {
            .search-box {
                flex-direction: column;
            }
            
            .file-details {
                flex-wrap: wrap;
                gap: 8px;
            }
            
            .result-item {
                flex-direction: column;
                align-items: flex-start;
            }
            
            .file-actions {
                margin-top: 10px;
                width: 100%;
            }
            
            .action-btn {
                flex: 1;
            }
        }
    </style>
</head>
<body>
    <header>
        <h1>Everything 本地文件搜索器</h1>
        <p class="subtitle">通过 Everything HTTP 服务器实现本地文件搜索、预览和管理功能</p>
    </header>
   
    <main>
        <section class="search-container">
            <div class="search-box">
                <input type="text" id="searchInput" placeholder="输入文件名、扩展名或路径 (如: *.pdf project.docx)" autofocus>
                <button id="searchButton">搜索文件</button>
            </div>
            
            <div class="filters">
                <div class="filter-group">
                    <label for="fileType">文件类型</label>
                    <select id="fileType">
                        <option value="">所有文件类型</option>
                        <option value=".pdf">DF 文档</option>
                        <option value=".doc,.docx">Word 文档</option>
                        <option value=".xls,.xlsx">Excel 表格</option>
                        <option value=".jpg,.jpeg,.png,.gif">图片文件</option>
                        <option value=".mp4,.avi,.mov">视频文件</option>
                        <option value=".mp3,.wav">音频文件</option>
                    </select>
                </div>
               
                <div class="filter-group">
                    <label for="searchPath">搜索路径</label>
                    <input type="text" id="searchPath" placeholder="如: C:\Projects\ D:\Documents\">
                </div>
               
                <div class="filter-group">
                    <label for="sortBy">排序方式</label>
                    <select id="sortBy">
                        <option value="date_modified:desc">最新修改</option>
                        <option value="date_modified:asc">最早修改</option>
                        <option value="size:desc">最大文件</option>
                        <option value="size:asc">最小文件</option>
                        <option value="name:asc">名称 (A-Z)</option>
                        <option value="name:desc">名称 (Z-A)</option>
                    </select>
                </div>
            </div>
            
            <div class="error-message" id="errorMessage">
                无法连接到 Everything HTTP 服务器。请确保 Everything 正在运行且 HTTP 服务器已启用。
            </div>
        </section>
        
        <section class="results-container">
            <div class="results-header">
                <h2>搜索结果</h2>
                <div id="resultCount">0 个文件</div>
            </div>
            
            <div class="loading-container" id="loadingIndicator">
                <div class="loading-spinner"></div>
                <p>正在搜索中...</p>
            </div>
            
            <div id="results">
                <div class="no-results">
                    <p>输入搜索条件并点击"搜索文件"按钮开始搜索</p>
                </div>
            </div>
        </section>
    </main>
   
    <div class="preview-container" id="previewContainer">
        <div class="preview-content">
            <div class="preview-header">
                <h3 id="previewFileName">文件预览</h3>
                <button class="close-preview" id="closePreview">&times;</button>
            </div>
            <div class="preview-body" id="previewBody"></div>
        </div>
    </div>
   
    <footer>
        <p>Everything 本地文件搜索器 &copy; 2023 | 需要 Everything v1.4+ 和启用的 HTTP 服务器</p>
    </footer>
   
    <script>
        // Everything HTTP 服务器配置
        const EVERYTHING_HTTP_URL = "http://localhost:8080";
        
        // DOM 元素
        const searchInput = document.getElementById('searchInput');
        const searchButton = document.getElementById('searchButton');
        const fileTypeSelect = document.getElementById('fileType');
        const searchPathInput = document.getElementById('searchPath');
        const sortBySelect = document.getElementById('sortBy');
        const resultsContainer = document.getElementById('results');
        const resultCountElement = document.getElementById('resultCount');
        const loadingIndicator = document.getElementById('loadingIndicator');
        const errorMessage = document.getElementById('errorMessage');
        const previewContainer = document.getElementById('previewContainer');
        const previewBody = document.getElementById('previewBody');
        const previewFileName = document.getElementById('previewFileName');
        const closePreview = document.getElementById('closePreview');
        
        // 文件图标映射
        const fileIcons = {
            'folder': '
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表