wordpress相册打造的视频弹出优化网站制作公司好吗
2026/1/2 5:56:25 网站建设 项目流程
wordpress相册打造的视频弹出,优化网站制作公司好吗,如何在百度建立自己的网站,企业品牌宣传型网站大文件上传解决方案 各位同行大佬们好#xff0c;作为一个在广东摸爬滚打多年的前端老油条#xff0c;最近接了个让我差点秃顶的项目——20G大文件上传系统#xff0c;还要兼容IE9#xff01;这感觉就像让我用竹篮子去打水还要不漏一样刺激… 需求分析#…大文件上传解决方案各位同行大佬们好作为一个在广东摸爬滚打多年的前端老油条最近接了个让我差点秃顶的项目——20G大文件上传系统还要兼容IE9这感觉就像让我用竹篮子去打水还要不漏一样刺激…需求分析客户这是要我老命啊20G大文件传输我寻思着这不是上传这是在往浏览器里塞一头大象啊文件夹保留层级客户说文件夹里有1000个分类文件这哪是文件夹这是个文件博物馆加密传输存储SM4、AES齐上阵比瑞士银行的保险箱还严实断点续传关了浏览器、重启电脑都不能丢进度这要求比我的记忆力靠谱多了非打包下载几万个文件直接下载这网速得比我的工资涨得还快才行兼容IE9Windows7IE9的组合让我梦回2012年青春啊最绝的是预算100元以内还要求7×24小时支持这价格连我家的路由器月租都不够啊兄弟们前端解决方案与IE9的世纪和解既然客户爸爸说了要用原生JS那咱们就用H5的File APIIndexedDB来整活穷逼版大文件上传 /* 祖传CSS兼容IE9 */ .upload-area { border: 2px dashed #ccc; padding: 20px; text-align: center; margin: 20px; background: #f9f9f9; } .progress-container { width: 100%; background-color: #f5f5f5; margin: 10px 0; height: 20px; position: relative; } .progress-bar { height: 100%; background-color: #4CAF50; width: 0%; transition: width 0.3s; } .progress-text { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: #333; font-size: 12px; } .file-item { margin: 10px 0; padding: 10px; border: 1px solid #eee; background: #fff; } .file-name { font-weight: bold; } .file-path { color: #666; font-size: 0.9em; margin-left: 10px; } .file-size { color: #888; font-size: 0.9em; margin-left: 10px; } .file-controls { margin-top: 5px; } button { padding: 5px 10px; margin-right: 5px; background: #f0f0f0; border: 1px solid #ddd; cursor: pointer; } button:hover { background: #e0e0e0; } 大文件上传兼容IE9版 拖放文件或文件夹到此处 或 选择文件/文件夹 等待上传文件... 开始上传 暂停 继续 加密方式 SM4国密 AES-256 // 上传队列 var uploadQueue []; var currentUpload null; var chunkSize 5 * 1024 * 1024; // 5MB分块 // 初始化 function init() { // 文件选择处理 document.getElementById(fileInput).addEventListener(change, function(e) { handleFiles(e.target.files); }); // 拖放处理 var dropArea document.getElementById(dropArea); dropArea.addEventListener(dragover, function(e) { e.preventDefault(); dropArea.style.borderColor #4CAF50; dropArea.style.background #f0fff0; }); dropArea.addEventListener(dragleave, function() { dropArea.style.borderColor #ccc; dropArea.style.background #f9f9f9; }); dropArea.addEventListener(drop, function(e) { e.preventDefault(); dropArea.style.borderColor #ccc; dropArea.style.background #f9f9f9; handleFiles(e.dataTransfer.files); }); // 加载未完成的传输 loadPendingTransfers(); } // 处理文件选择 function handleFiles(files) { var queueContainer document.getElementById(uploadQueue); queueContainer.innerHTML ; for (var i 0; i files.length; i) { var file files[i]; addFileToQueue(file); } } // 添加文件到队列 function addFileToQueue(file) { var fileItem { id: generateFileId(file), name: file.name, path: file.webkitRelativePath || , size: file.size, progress: 0, status: pending, file: file }; uploadQueue.push(fileItem); renderQueue(); } // 渲染队列 function renderQueue() { var queueContainer document.getElementById(uploadQueue); queueContainer.innerHTML ; if (uploadQueue.length 0) { queueContainer.innerHTML p等待上传文件.../p; return; } for (var i 0; i uploadQueue.length; i) { var item uploadQueue[i]; var itemElement document.createElement(div); itemElement.className file-item; itemElement.innerHTML divspanclassfile-name${item.name}/spanspanclassfile-path${item.path}/spanspanclassfile-size${formatFileSize(item.size)}/span/divdivclassprogress-containerdivclassprogress-barstylewidth:${item.progress}%/divspanclassprogress-text${item.progress}%/span/divdivclassfile-controlsbutton onclickpauseItem(${item.id}) ${item.status ! uploading ? disabled : }暂停/buttonbutton onclickresumeItem(${item.id}) ${item.status ! paused ? disabled : }继续/buttonbuttononclickcancelItem(${item.id})取消/button/div; queueContainer.appendChild(itemElement); } } // 开始上传 function startUpload() { if (uploadQueue.length 0) return; currentUpload uploadQueue.find(item item.status pending); if (currentUpload) { currentUpload.status uploading; uploadFile(currentUpload); } } // 上传文件 function uploadFile(fileItem) { var file fileItem.file; var totalChunks Math.ceil(file.size / chunkSize); // 从本地存储加载断点 var resumeChunk localStorage.getItem(resume_ fileItem.id) || 0; // 上传分块 for (var chunkIndex resumeChunk; chunkIndex totalChunks; chunkIndex) { if (fileItem.status paused) break; var start chunkIndex * chunkSize; var end Math.min(start chunkSize, file.size); var chunk file.slice(start, end); var formData new FormData(); formData.append(fileId, fileItem.id); formData.append(chunkIndex, chunkIndex); formData.append(totalChunks, totalChunks); formData.append(fileName, fileItem.name); formData.append(filePath, fileItem.path); formData.append(fileSize, fileItem.size); formData.append(chunkData, chunk); formData.append(encryption, document.getElementById(encryptionType).value); formData.append(encryptionKey, document.getElementById(encryptionKey).value); // AJAX上传兼容IE9 var xhr new XMLHttpRequest(); xhr.open(POST, /api/upload/chunk, false); // 同步上传 xhr.upload.onprogress function(e) { var loaded chunkIndex * chunkSize e.loaded; fileItem.progress Math.round((loaded / fileItem.size) * 100); renderQueue(); }; xhr.onreadystatechange function() { if (xhr.readyState 4) { if (xhr.status 200) { // 保存断点 localStorage.setItem(resume_ fileItem.id, chunkIndex 1); if (chunkIndex totalChunks - 1) { // 合并文件 mergeFile(fileItem.id); fileItem.status completed; startUpload(); // 开始下一个文件 } } else { console.error(上传失败:, xhr.responseText); fileItem.status error; renderQueue(); } } }; try { xhr.send(formData); } catch (e) { console.error(上传出错:, e); fileItem.status error; renderQueue(); break; } } } // 暂停上传 function pauseUpload() { if (currentUpload) { currentUpload.status paused; renderQueue(); } } // 继续上传 function resumeUpload() { if (currentUpload currentUpload.status paused) { currentUpload.status uploading; uploadFile(currentUpload); } } // 暂停单个项目 function pauseItem(fileId) { var item uploadQueue.find(item item.id fileId); if (item) { item.status paused; renderQueue(); } } // 继续单个项目 function resumeItem(fileId) { var item uploadQueue.find(item item.id fileId); if (item item.status paused) { item.status uploading; uploadFile(item); } } // 取消单个项目 function cancelItem(fileId) { var index uploadQueue.findIndex(item item.id fileId); if (index 0) { // 通知后端取消上传 cancelUpload(fileId); // 从队列移除 uploadQueue.splice(index, 1); renderQueue(); } } // 合并文件 function mergeFile(fileId) { var xhr new XMLHttpRequest(); xhr.open(POST, /api/upload/merge, false); xhr.setRequestHeader(Content-Type, application/x-www-form-urlencoded); xhr.onreadystatechange function() { if (xhr.readyState 4 xhr.status 200) { console.log(文件合并成功:, xhr.responseText); localStorage.removeItem(resume_ fileId); } }; xhr.send(fileId encodeURIComponent(fileId) encryption encodeURIComponent(document.getElementById(encryptionType).value)); } // 取消上传 function cancelUpload(fileId) { var xhr new XMLHttpRequest(); xhr.open(POST, /api/upload/cancel, false); xhr.setRequestHeader(Content-Type, application/x-www-form-urlencoded); xhr.send(fileId encodeURIComponent(fileId)); } // 加载未完成的传输 function loadPendingTransfers() { var xhr new XMLHttpRequest(); xhr.open(GET, /api/upload/pending, false); xhr.onreadystatechange function() { if (xhr.readyState 4 xhr.status 200) { var pendingFiles JSON.parse(xhr.responseText); pendingFiles.forEach(function(fileInfo) { uploadQueue.push({ id: fileInfo.fileId, name: fileInfo.fileName, path: fileInfo.filePath, size: fileInfo.fileSize, progress: fileInfo.progress, status: paused }); }); renderQueue(); } }; xhr.send(); } // 生成文件ID function generateFileId(file) { return file.name _ file.size _ file.lastModified; } // 格式化文件大小 function formatFileSize(bytes) { if (bytes 0) return 0 B; var k 1024; var sizes [B, KB, MB, GB, TB]; var i Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) sizes[i]; } // 初始化 window.onload init;前端关键功能说明1. 兼容IE9的黑魔法使用条件注释只对IE9及以下浏览器加载polyfilljson2.js解决IE9没有JSON对象的问题promise-polyfill解决IE9不支持Promise的问题2. 文件夹上传核心代码// 文件选择元素添加webkitdirectory和directory属性// 处理文件时保留路径信息functionhandleFiles(files){for(vari0;ifiles.length;i){varfilefiles[i];varfileItem{name:file.name,path:file.webkitRelativePath||,// 保留相对路径size:file.size// ...};uploadQueue.push(fileItem);}}3. 断点续传实现// 上传前检查本地是否有断点记录varresumeChunklocalStorage.getItem(resume_fileItem.id)||0;// 上传成功后保存断点localStorage.setItem(resume_fileItem.id,chunkIndex1);// 文件合并成功后清理断点localStorage.removeItem(resume_fileItem.id);4. 加密传输伪实现// 实际项目中应该使用Web Crypto API或相应库formData.append(encryption,document.getElementById(encryptionType).value);formData.append(encryptionKey,document.getElementById(encryptionKey).value);如何与后端对接需要后端提供的API接口分块上传接口POST /api/upload/chunk 参数 - fileId: 文件唯一ID - chunkIndex: 当前分块索引 - totalChunks: 总分块数 - fileName: 文件名 - filePath: 文件相对路径文件夹结构 - fileSize: 文件大小 - chunkData: 分块数据 - encryption: 加密算法 - encryptionKey: 加密密钥合并文件接口POST /api/upload/merge 参数 - fileId: 文件唯一ID - encryption: 加密算法取消上传接口POST /api/upload/cancel 参数 - fileId: 文件唯一ID获取未完成任务接口GET /api/upload/pending 返回 [ { fileId: string, fileName: string, filePath: string, fileSize: number, progress: number } ]部署注意事项IE9兼容性确保服务器正确设置X-UA-Compatible头添加MIME类型.json application/json大文件上传配置Nginx/Apache的上传大小限制设置PHP的upload_max_filesize和post_max_size断点续传确保localStorage可用IE8支持对于隐私模式需要降级使用cookie存储加密传输实际项目中应该使用HTTPS前端加密应该使用Web Crypto API或相应polyfill最后吐槽100块预算还要兼容IE9甲方是不是对程序员有什么误解20G文件上传建议先问问甲方他们服务器硬盘够不够大7x24小时免费技术支持我连7x24小时睡觉都保证不了…要源代码要文档要一条龙服务100块连个外卖都点不了好吗加群374992201领红包兄弟有这功夫不如多接几个项目…不过既然你都看到这里了代码拿去用吧记得请我喝奶茶至少得是喜茶级别的将组件复制到项目中示例中已经包含此目录引入组件配置接口地址接口地址分别对应文件初始化文件数据上传文件进度文件上传完毕文件删除文件夹初始化文件夹删除文件列表参考http://www.ncmem.com/doc/view.aspx?ide1f49f3e1d4742e19135e00bd41fa3de处理事件启动测试启动成功效果数据库效果预览文件上传文件刷新续传支持离线保存文件进度在关闭浏览器刷新浏览器后进行不丢失仍然能够继续上传文件夹上传支持上传文件夹并保留层级结构同样支持进度信息离线保存刷新页面关闭页面重启系统不丢失上传进度。下载示例点击下载完整示例

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询