如何用JavaScript获取本地文件列表,实现多文件夹文件动态展示?
Hey there, I totally get your frustration—you want an HTML page that automatically shows the ~500 files across 50 subfolders on your laptop, but static links won't cut it because files are always changing. The core issue here is browser security restrictions: plain frontend JavaScript can't directly read the local file system when running from a file:// URL. Let's walk through why your current code isn't working, and then cover practical solutions.
Why Your Current Code Doesn't Dynamically Fetch Files
Your MakeLinks2 function works fine for hardcoded filenames, but there's no way for frontend JS to scan your local pdfs/ directory automatically. Browsers block this to prevent malicious scripts from accessing sensitive local files without your permission. Also, quick notes on your code's small issues:
- You accidentally wrote
text += '</ul>';at the start of the function instead of<ul> - When assigning to
window.onload, you should pass a function reference, not call the function immediately (right now it runs before the page finishes loading)
Fixed snippet for the function part (still uses hardcoded files, but fixes syntax/execution timing):
// where are we? var loc = window.location.pathname; var dir = loc.substring(0, loc.lastIndexOf('/')); document.write(loc + '<br>'); document.write(dir); // make links from a list passed to it function MakeLinks2(files) { var text = ""; var i; text += '<ul>'; // Fixed opening tag for (i = 0; i < files.length; i++) { text += '<li><a href="pdfs/' + files[i] + '">' + files[i] + '</a></li>'; } text += '</ul>'; document.getElementById("external").innerHTML = text; } // Pass a function reference instead of calling immediately window.onload = function() { MakeLinks2(["1.pdf", "2.pdf", "3.pdf", "4.pdf", "1.pdf", "2.pdf", "3.pdf", "40.pdf"]); };
Practical Solutions to Dynamically List Local Files
1. Use Node.js to Run a Local Static Server (Best for Automatic Scanning)
Node.js lets you read the local file system and generate the file list dynamically when you access the page. Here's how to set this up:
Step 1: Install Node.js
Grab the official Node.js distribution if you don't have it already.
Step 2: Create a Server Script
Make a file named server.js in your project folder:
const http = require('http'); const fs = require('fs'); const path = require('path'); const PORT = 3000; http.createServer((req, res) => { // Serve the main HTML page if (req.url === '/') { fs.readFile(path.join(__dirname, 'index.html'), 'utf8', (err, html) => { if (err) { res.writeHead(500); res.end('Error loading index.html'); return; } // Scan the pdfs directory and all subdirectories function scanDir(dir, fileList = []) { const files = fs.readdirSync(dir); files.forEach(file => { const fullPath = path.join(dir, file); if (fs.statSync(fullPath).isDirectory()) { scanDir(fullPath, fileList); } else { // Convert path to relative URL for links const relativePath = path.relative(__dirname, fullPath); fileList.push(relativePath); } }); return fileList; } const pdfFiles = scanDir(path.join(__dirname, 'pdfs')); // Replace placeholder in index.html with dynamic file list const fileListHtml = pdfFiles.map(file => `<li><a href="${file}">${path.basename(file)}</a></li>` ).join(''); const finalHtml = html.replace('{{FILE_LIST}}', `<ul>${fileListHtml}</ul>`); res.writeHead(200, {'Content-Type': 'text/html'}); res.end(finalHtml); }); } // Serve static files (pdfs, etc.) else { const filePath = path.join(__dirname, req.url); fs.readFile(filePath, (err, data) => { if (err) { res.writeHead(404); res.end('File not found'); return; } // Set correct content type for PDFs const contentType = req.url.endsWith('.pdf') ? 'application/pdf' : 'text/html'; res.writeHead(200, {'Content-Type': contentType}); res.end(data); }); } }).listen(PORT, () => { console.log(`Server running at http://localhost:${PORT}/`); });
Step 3: Create Your index.html
Make an index.html file with a placeholder for the file list:
<!DOCTYPE html> <html> <head> <title>Local PDF List</title> </head> <body> <h1>My PDF Files</h1> <div id="external">{{FILE_LIST}}</div> </body> </html>
Step 4: Run the Server
Open your terminal, navigate to your project folder, and run:
node server.js
Then open http://localhost:3000 in your browser—you'll see a dynamic list of all PDFs in your pdfs/ folder and subfolders, which updates automatically whenever you add/remove files (just refresh the page).
2. Use the File API (Manual Folder Selection)
If you don't want to run a server, you can let users manually select the pdfs/ folder using the browser's File API. This doesn't require backend code, but users have to select the folder each time:
<!DOCTYPE html> <html> <head> <title>Select PDF Folder</title> </head> <body> <input type="file" id="folderPicker" webkitdirectory directory> <div id="fileList"></div> <script> document.getElementById('folderPicker').addEventListener('change', (e) => { const files = e.target.files; const fileListDiv = document.getElementById('fileList'); let html = '<ul>'; for (const file of files) { // Create a blob URL to access the local file const url = URL.createObjectURL(file); html += `<li><a href="${url}" target="_blank">${file.name}</a></li>`; } html += '</ul>'; fileListDiv.innerHTML = html; }); </script> </body> </html>
Note: This works in most modern browsers, but relies on the user selecting the folder manually each time they open the page.
3. Use Electron (Desktop App Experience)
If you want a fully native-like app that can automatically scan your files without a server, Electron is a great option. It lets you use Node.js file system APIs directly in a browser-like window. You'd create a simple Electron app that scans your pdfs/ folder on launch and displays the list—this gives you the flexibility of frontend JS with full access to the local file system.
内容的提问来源于stack exchange,提问作者dn13




