求助:如何在纯HTML和JS中展示Firebase Storage中的PDF文件
解决方案:Firebase Storage PDF展示实现
核心思路
- 从
localStorage读取已上传的PDF文件路径(后续可迁移到Firebase Realtime Database/Firestore实现多端同步) - 通过Firebase Storage API获取PDF的公开下载URL
- 使用HTML的
<embed>或<iframe>标签在页面嵌入预览,同时提供下载链接 - 配置Storage权限确保前端能读取文件
步骤1:修改HTML,添加PDF展示容器
在你的页面(管理员后台或首页)中添加展示PDF的区域:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Cloud Storage Application</title> <link rel="stylesheet" href="style.css"> <style> /* 简单的PDF卡片样式,可自定义 */ .pdf-display-container { margin-top: 30px; } .pdf-card { display: inline-block; margin: 10px; padding: 10px; border: 1px solid #ddd; } .download-btn { display: block; margin-top: 10px; text-align: center; } </style> </head> <body> <h1>Admin Dashboard</h1> <!-- 原上传区域保留 --> <div class="upload-area"> <button class="upload">Upload</button> <div class="progress-container"> <div class="progress"></div> </div> <div class="percent">0%</div> <div class="controls"> <svg class="pause" xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"> <path d="M0 0h24v24H0V0z" fill="none" /> <path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z" /> </svg> <svg class="resume" xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"> <path d="M8 6.82v10.36c0 .79.87 1.27 1.54.84l8.14-5.18c.62-.39.62-1.29 0-1.69L9.54 5.98C8.87 5.55 8 6.03 8 6.82z" /> </svg> <svg class="cancel" xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"> <path d="M0 0h24v24H0V0z" fill="none" /> <path d="M18.3 5.71c-.39-.39-1.02-.39-1.41 0L12 10.59 7.11 5.7c-.39-.39-1.02-.39-1.41 0-.39.39-.39 1.02 0 1.41L10.59 12 5.7 16.89c-.39.39-.39 1.02 0 1.41.39.39 1.02.39 1.41 0L12 13.41l4.89 4.89c.39.39 1.02.39 1.41 0 .39-.39.39-1.02 0-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4z" /> </svg> </div> <input type="file" class="hidden-upload-btn" style="display: none;"> </div> <!-- 新增PDF展示区域 --> <div class="pdf-display-container"> <h2>已上传PDF预览</h2> <div id="pdf-list"></div> </div> <script src="https://www.gstatic.com/firebasejs/6.0.2/firebase.js"></script> <script src="script.js"></script> </body> </html>
步骤2:更新JS代码,实现PDF列表渲染
在你的script.js中添加以下函数,并修改现有逻辑:
// For Firebase JS SDK v7.20.0 and later, measurementId is optional const firebaseConfig = { apiKey: "你的API密钥", authDomain: "你的Auth域名", projectId: "你的项目ID", storageBucket: "你的存储桶", messagingSenderId: "你的Sender ID", appId: "你的App ID", measurementId: "你的Measurement ID" }; firebase.initializeApp(firebaseConfig); // 获取DOM元素 var upload = document.getElementsByClassName('upload')[0]; var hiddenBtn = document.getElementsByClassName('hidden-upload-btn')[0]; var progress = document.getElementsByClassName('progress')[0]; var percent = document.getElementsByClassName('percent')[0]; var pause = document.getElementsByClassName('pause')[0]; var resume = document.getElementsByClassName('resume')[0]; var cancel = document.getElementsByClassName('cancel')[0]; // 触发文件选择 upload.onclick = function () { hiddenBtn.click(); } // 初始化localStorage存储文件元数据 if(!localStorage.getItem("uploaded-metadata")){ localStorage.setItem('uploaded-metadata', '[]') } // 文件上传逻辑 hiddenBtn.onchange = function () { var file = hiddenBtn.files[0]; // 重命名文件避免覆盖 var name = file.name.split('.').shift() + Math.floor(Math.random() * 10) + 10 + '.' + file.name.split('.').pop(); var type = file.type.split('/')[0]; var path = type + '/' + name; var storageRef = firebase.storage().ref(path); var uploadTask = storageRef.put(file); // 上传控制按钮逻辑 pause.onclick = function () { uploadTask.pause(); resume.style.display = 'inline-block'; pause.style.display = 'none'; } resume.onclick = function () { uploadTask.resume(); resume.style.display = 'none'; pause.style.display = 'inline-block'; } cancel.onclick = function () { uploadTask.cancel(); progress.style.width = '0%'; percent.innerHTML = '0%'; } upload.disabled = true; percent.innerHTML = '0%'; // 上传进度监听 uploadTask.on('state_changed', (snapshot) => { var progressValue = String((snapshot.bytesTransferred / snapshot.totalBytes) * 100).split('.')[0]; progress.style.width = progressValue + '%'; percent.innerHTML = progressValue + '%'; }, (error) => { console.log(error) }, () => { // 上传完成后更新元数据并重新渲染PDF列表 var metadata = JSON.parse(localStorage.getItem('uploaded-metadata')); metadata.unshift(path); localStorage.setItem("uploaded-metadata", JSON.stringify(metadata)); percent.innerHTML = 'DONE'; upload.disabled = false; hiddenBtn.value = null; renderPDFList(); // 上传完成后刷新列表 } ) } // 页面加载时自动渲染PDF列表 window.onload = function() { renderPDFList(); }; // 渲染已上传的PDF列表 function renderPDFList() { const pdfListContainer = document.getElementById('pdf-list'); const uploadedMetadata = JSON.parse(localStorage.getItem('uploaded-metadata')) || []; // 过滤出PDF格式的文件 const pdfFiles = uploadedMetadata.filter(filePath => filePath.toLowerCase().endsWith('.pdf')); if (pdfFiles.length === 0) { pdfListContainer.innerHTML = '<p>暂无已上传的PDF文件</p>'; return; } // 清空容器避免重复渲染 pdfListContainer.innerHTML = ''; pdfFiles.forEach(filePath => { const storageRef = firebase.storage().ref(filePath); // 获取PDF的公开下载链接 storageRef.getDownloadURL() .then(downloadUrl => { // 创建PDF预览卡片 const pdfCard = document.createElement('div'); pdfCard.className = 'pdf-card'; // 嵌入PDF预览 const pdfEmbed = document.createElement('embed'); pdfEmbed.src = downloadUrl; pdfEmbed.type = 'application/pdf'; pdfEmbed.width = '300'; pdfEmbed.height = '400'; // 添加下载按钮 const downloadBtn = document.createElement('a'); downloadBtn.href = downloadUrl; downloadBtn.download = filePath.split('/').pop(); // 提取文件名 downloadBtn.textContent = '下载此PDF'; downloadBtn.className = 'download-btn'; pdfCard.appendChild(pdfEmbed); pdfCard.appendChild(downloadBtn); pdfListContainer.appendChild(pdfCard); }) .catch(error => { console.error('获取PDF链接失败:', error); pdfListContainer.innerHTML += `<p>加载文件失败:${filePath}</p>`; }); }); } // 修复原openUrl函数的未定义变量问题 function openUrl(v) { const path = v.parentElement.getAttribute('data-file-name'); const storageRef = firebase.storage().ref(path); storageRef.getDownloadURL() .then(url => { // 在新窗口打开PDF window.open(url, '_blank'); }) .catch(error => { console.log(error); }); }
步骤3:配置Firebase Storage权限
默认情况下,Firebase Storage的文件只有上传者能读取,若要在首页公开展示,需修改Storage规则:
- 打开Firebase控制台 -> 存储 -> 规则
- 将默认规则替换为:
rules_version = '2'; service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read: if true; // 允许公开读取(后续可结合登录限制) allow write: if request.auth != null; // 仅登录用户可上传 } } }
注意:如果后续要做权限控制,可以把
allow read: if true;改成基于用户身份的验证规则,比如request.auth != null或更细粒度的权限。
关键说明
- 当前用
localStorage存储文件路径,仅在单设备有效,后续若要多端同步,建议改用Firebase Realtime Database或Firestore存储文件元数据 <embed>标签在大部分浏览器支持PDF预览,若需要兼容更多场景,可替换为<iframe>标签- 若PDF文件较大,可添加加载状态提示优化用户体验
内容的提问来源于stack exchange,提问作者aadrian
相关产品推荐
相关产品推荐

