新闻排版设计用什么软件怎么优化一个网站关键词

张小明 2026/1/3 20:44:54
新闻排版设计用什么软件,怎么优化一个网站关键词,浙江省建筑诚信平台查询系统,虚拟主机安装wordpress大文件上传系统开发指南#xff08;基于原生JSSpringBoot#xff09; 项目概述 大家好#xff0c;我是一个在浙江奋斗的Java程序员#xff0c;最近接了个刺激的外包项目 - 开发一个支持20G大文件上传下载的系统#xff0c;还要兼容IE9这种上古浏览器。客户要…大文件上传系统开发指南基于原生JSSpringBoot项目概述大家好我是一个在浙江奋斗的Java程序员最近接了个刺激的外包项目 - 开发一个支持20G大文件上传下载的系统还要兼容IE9这种上古浏览器。客户要求使用原生JS实现不能用jQuery等库支持文件夹上传保留层级结构还要加密传输和断点续传。预算只有100元但需要提供完整技术支持和源代码。这活儿听着就刺激但咱是谁是打不死的小强下面我就分享一下我的解决方案和部分代码实现。技术选型前端Vue3 CLI 原生JavaScript兼容IE9后端SpringBoot Tomcat数据库MySQL主要存用户信息和文件元数据文件存储服务器本地文件系统加密SM4国密和AES系统架构浏览器(IE9) ←HTTP→ SpringBoot后端 ←本地IO→ 文件存储 ↑ MySQL元数据前端实现关键代码1. 文件夹上传组件兼容IE9export default { data() { return { fileList: [], chunkSize: 5 * 1024 * 1024, // 5MB分片 concurrent: 3 // 并发上传数 } }, methods: { triggerFileInput() { document.getElementById(fileInput).click(); }, handleFileChange(e) { const files e.target.files; if (!files.length) return; // 处理文件夹结构 const fileTree this.buildFileTree(files); this.prepareUpload(fileTree); }, // 构建文件树结构保留文件夹层级 buildFileTree(files) { const tree {}; for (let i 0; i files.length; i) { const file files[i]; const path file.webkitRelativePath || file.relativePath || file.name; const parts path.split(/); // 添加文件信息 const fileName parts[parts.length - 1]; current[fileName] { file: file, relativePath: path, size: file.size, chunks: Math.ceil(file.size / this.chunkSize), uploadedChunks: 0, progress: 0, status: 等待上传 }; } return tree; }, // 准备上传队列 prepareUpload(tree) { const flattenFiles []; const traverse (node, path ) { for (const key in node) { if (key __files__ || key __dirs__) continue; const newPath path ? ${path}/${key} : key; if (node[key].file) { // 是文件 flattenFiles.push({ ...node[key], relativePath: newPath }); } else { // 是目录继续遍历 traverse(node[key].__dirs__, newPath); } } }; traverse(tree); this.fileList flattenFiles; this.startUpload(); }, // 开始上传 startUpload() { const activeUploads 0; const uploadNext () { if (activeUploads this.concurrent) return; const file this.fileList.find(f f.status 等待上传); if (!file) { if (this.fileList.every(f f.status 上传完成)) { this.$emit(upload-complete); } return; } }; uploadNext(); }, // 分片上传文件 async uploadFile(fileEntry) { const file fileEntry.file; const fileId this.generateFileId(file); // 检查断点续传信息 const resumeInfo this.getResumeInfo(fileId); let startChunk resumeInfo ? resumeInfo.uploadedChunks : 0; for (let i startChunk; i fileEntry.chunks; i) { const start i * this.chunkSize; const end Math.min(start this.chunkSize, file.size); const chunk file.slice(start, end); // 读取分片内容兼容IE9 const chunkData await this.readFileAsArrayBuffer(chunk); // 加密处理这里简化实际应该用Web Crypto API或polyfill const encryptedData this.encryptData(chunkData, AES); // 实际应该用SM4 const formData new FormData(); formData.append(fileId, fileId); formData.append(chunkIndex, i); formData.append(totalChunks, fileEntry.chunks); formData.append(relativePath, fileEntry.relativePath); formData.append(fileSize, file.size); formData.append(chunk, new Blob([encryptedData])); formData.append(fileName, file.name); } // 所有分片上传完成通知服务器合并 await this.mergeFile(fileId, fileEntry.relativePath, file.size, file.name); fileEntry.status 上传完成; this.clearResumeInfo(fileId); }, // 以下是兼容IE9的工具方法 readFileAsArrayBuffer(file) { return new Promise((resolve) { const reader new FileReader(); reader.onload (e) resolve(e.target.result); reader.readAsArrayBuffer(file); }); }, encryptData(data, algorithm) { // 实际项目中应该使用Web Crypto API或polyfill // 这里简化处理实际加密代码会更复杂 if (typeof data string) { return btoa(data); // 简单base64模拟加密 } else { const bytes new Uint8Array(data); let result ; for (let i 0; i bytes.length; i) { result String.fromCharCode(bytes[i]); } return btoa(result); } }, async uploadChunk(formData) { return new Promise((resolve, reject) { const xhr new XMLHttpRequest(); xhr.open(POST, /api/upload/chunk, true); xhr.onload () { if (xhr.status 200 xhr.status 300) { resolve(JSON.parse(xhr.responseText)); } else { reject(new Error(上传失败)); } }; xhr.onerror () reject(new Error(网络错误)); xhr.send(formData); }); }, async mergeFile(fileId, relativePath, fileSize, fileName) { return new Promise((resolve, reject) { const xhr new XMLHttpRequest(); xhr.open(POST, /api/upload/merge, true); xhr.setRequestHeader(Content-Type, application/json); xhr.onload () { if (xhr.status 200 xhr.status 300) { resolve(JSON.parse(xhr.responseText)); } else { reject(new Error(合并失败)); } }; xhr.onerror () reject(new Error(网络错误)); xhr.send(JSON.stringify({ fileId, relativePath, fileSize, fileName })); }); }, // 断点续传相关方法使用localStorage存储 generateFileId(file) { // 简单生成文件ID实际应该更可靠 return ${file.name}-${file.size}-${file.lastModified}; }, getResumeInfo(fileId) { const info localStorage.getItem(upload_resume_${fileId}); return info ? JSON.parse(info) : null; }, saveResumeInfo(fileId, fileEntry) { localStorage.setItem(upload_resume_${fileId}, JSON.stringify({ uploadedChunks: fileEntry.uploadedChunks, relativePath: fileEntry.relativePath, fileSize: fileEntry.size, fileName: fileEntry.file.name })); }, clearResumeInfo(fileId) { localStorage.removeItem(upload_resume_${fileId}); }, formatSize(bytes) { if (bytes 0) return 0 Bytes; const k 1024; const sizes [Bytes, KB, MB, GB, TB]; const i Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) sizes[i]; } } }后端实现SpringBoot关键代码1. 文件上传控制器RestControllerRequestMapping(/api/upload)publicclassFileUploadController{privatestaticfinalStringUPLOAD_DIR/var/bigfileupload/;// 实际应该从配置读取privatestaticfinalintCHUNK_SIZE5*1024*1024;// 5MBPostMapping(/chunk)publicResponseEntityuploadChunk(RequestParam(fileId)StringfileId,RequestParam(chunkIndex)intchunkIndex,RequestParam(totalChunks)inttotalChunks,RequestParam(relativePath)StringrelativePath,RequestParam(fileSize)longfileSize,RequestParam(fileName)StringfileName,RequestParam(chunk)MultipartFilechunk)throwsIOException{// 创建临时目录StringtempDirUPLOAD_DIRtemp/fileId/;FiletempDirFilenewFile(tempDir);if(!tempDirFile.exists()){tempDirFile.mkdirs();}// 保存分片实际应该先解密StringchunkPathtempDirchunkIndex;chunk.transferTo(newFile(chunkPath));// 记录上传进度实际应该用数据库UploadProgressprogressnewUploadProgress();progress.setFileId(fileId);progress.setUploadedChunks(chunkIndex1);progress.setTotalChunks(totalChunks);progress.setRelativePath(relativePath);progress.setFileSize(fileSize);progress.setFileName(fileName);// saveToDatabase(progress); // 实际应该存数据库returnResponseEntity.ok().body(Map.of(status,success,chunkIndex,chunkIndex,fileId,fileId));}PostMapping(/merge)publicResponseEntitymergeFile(RequestBodyMergeRequestrequest)throwsIOException,NoSuchAlgorithmException{StringfileIdrequest.getFileId();StringtempDirUPLOAD_DIRtemp/fileId/;FiletempDirFilenewFile(tempDir);if(!tempDirFile.exists()){returnResponseEntity.badRequest().body(Map.of(error,临时文件不存在));}// 创建目标目录结构StringrelativePathrequest.getRelativePath();StringtargetPathUPLOAD_DIRrelativePath;FiletargetFilenewFile(targetPath);}// 下载文件接口非打包方式GetMapping(/download)publicResponseEntitydownloadFile(RequestParamStringfilePath,HttpServletResponseresponse)throwsIOException{// 设置响应头HttpHeadersheadersnewHttpHeaders();headers.add(HttpHeaders.CONTENT_DISPOSITION,attachment; filename\file.getName()\);headers.add(HttpHeaders.CONTENT_TYPE,Files.probeContentType(file.toPath()));headers.add(HttpHeaders.CONTENT_LENGTH,String.valueOf(file.length()));returnResponseEntity.ok().headers(headers).body(resource);}// 文件夹下载递归下载GetMapping(/download/folder)publicvoiddownloadFolder(RequestParamStringfolderPath,HttpServletResponseresponse)throwsIOException{// 实际实现应该递归遍历文件夹生成zip或逐个文件下载// 这里简化处理实际项目中需要更复杂的实现response.setContentType(application/zip);response.setHeader(Content-Disposition,attachment; filename\newFile(folderPath).getName().zip\);// 实际应该使用ZipOutputStream打包// 这里只是示例实际不会这样实现try(ServletOutputStreamoutresponse.getOutputStream()){out.write(这不是真正的zip文件实际应该递归打包文件夹.getBytes());}}}2. 数据库实体类EntityTable(namefile_metadata)publicclassFileMetadata{IdGeneratedValue(strategyGenerationType.IDENTITY)privateLongid;privateStringfileId;privateStringfilePath;privateStringfileName;privatelongfileSize;privateDateuploadTime;// getters and setters}兼容IE9的注意事项XMLHttpRequestIE9不支持FormData但支持XMLHttpRequest上传文件FileReaderIE10才完全支持IE9需要polyfillBlobIE10支持IE9需要使用BlobBuilder加密Web Crypto API在IE9不可用需要使用第三方库如CryptoJSIE9兼容的加密方案示例// 在index.html中引入CryptoJS//// 修改encryptData方法encryptData(data,algorithm){if(algorithmAES){// 使用CryptoJS进行AES加密constkeyCryptoJS.enc.Utf8.parse(1234567890123456);// 实际应该从安全配置读取constivCryptoJS.enc.Utf8.parse(1234567890123456);letdataToEncrypt;if(typeofdatastring){dataToEncryptdata;}else{// 如果是ArrayBuffer转换为字符串constbytesnewUint8Array(data);letstr;for(leti0;ibytes.length;i){strString.fromCharCode(bytes[i]);}dataToEncryptstr;}constencryptedCryptoJS.AES.encrypt(dataToEncrypt,key,{iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7});returnencrypted.toString();}// 其他算法...returndata;// 未加密}部署说明前端构建npminstallnpmrun build将生成的dist目录内容部署到Tomcat的webapps/ROOT目录后端配置修改application.propertiesserver.port8080 spring.servlet.multipart.max-file-size21GB spring.servlet.multipart.max-request-size21GB file.upload-dir/var/bigfileupload/确保上传目录存在且有写入权限mkdir-p /var/bigfileupload/tempchmod777/var/bigfileupload数据库初始化创建MySQL数据库并执行SQL脚本CREATETABLEfile_metadata(idBIGINTAUTO_INCREMENTPRIMARYKEY,file_idVARCHAR(255)NOTNULL,file_pathTEXTNOTNULL,file_nameVARCHAR(255)NOTNULL,file_sizeBIGINTNOTNULL,upload_timeDATETIMENOTNULL);开发文档要点系统功能大文件分片上传支持20GB文件夹上传保留层级结构断点续传基于localStorage加密传输和存储AES/SM4兼容IE9等主流浏览器API文档POST /api/upload/chunk- 上传文件分片POST /api/upload/merge- 合并文件分片GET /api/upload/download- 下载单个文件GET /api/upload/download/folder- 下载整个文件夹部署文档环境要求JDK 8, Node.js, MySQL, Tomcat 8配置文件说明初始化脚本总结这个项目确实挑战不小但通过合理的分片上传、断点续传机制和兼容性处理我们还是能够实现客户的需求。关键点在于前端使用原生JS实现文件夹结构解析和上传队列管理后端提供分片上传和合并接口使用localStorage存储上传进度实现断点续传通过CryptoJS等库实现兼容IE9的加密由于预算有限我省略了一些高级功能如完整的SM4加密实现实际需要引入Bouncy Castle等库分布式存储支持详细的权限控制完善的错误处理和日志如果需要更完整的实现建议考虑使用WebUploader等成熟库但需要处理兼容性问题增加预算购买商业组件分阶段开发先实现核心功能最后欢迎加入我们的QQ群374992201一起交流技术合作接单群里经常有红包和技术分享还有项目合作机会哦导入项目导入到Eclipse点南查看教程导入到IDEA点击查看教程springboot统一配置点击查看教程工程NOSQLNOSQL示例不需要任何配置可以直接访问测试创建数据表选择对应的数据表脚本这里以SQL为例修改数据库连接信息访问页面进行测试文件存储路径up6/upload/年/月/日/guid/filename效果预览文件上传文件刷新续传支持离线保存文件进度在关闭浏览器刷新浏览器后进行不丢失仍然能够继续上传文件夹上传支持上传文件夹并保留层级结构同样支持进度信息离线保存刷新页面关闭页面重启系统不丢失上传进度。下载示例点击下载完整示例
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

网站建设的征求意见稿云安区学校网站建设统计表

深入探索Shell编程:for循环与字符串、数字处理 1. for循环的基本概念 在Shell编程中,for循环是一种强大的流程控制结构,与while和until循环不同,它提供了在循环中处理序列的方法,在编程中非常实用,是bash脚本中常用的结构。在现代bash版本中,for循环有两种形式。 2. …

张小明 2025/12/22 6:26:15 网站建设

生活信息网站建设女生学视觉传达设计好就业吗

React 虚拟化的过度使用React 开发者似乎把虚拟化库(比如 react-window 和 react-virtualized)当成了渲染列表的万能药。从逻辑上看,这似乎很合理:用户一次只能看到 10 个项目,为什么要渲染全部 1000 个?虚…

张小明 2025/12/22 2:57:51 网站建设

做下载类型网站怎样划算泰安人才网网上办事

💡实话实说:CSDN上做毕设辅导的都是专业技术服务,大家都要生活,这个很正常。我和其他人不同的是,我有自己的项目库存,不需要找别人拿货再加价。我就是个在校研究生,兼职赚点饭钱贴补生活费&…

张小明 2025/12/22 3:37:34 网站建设

做正规网站有哪些vip域名做网站好不好

第一章:为什么你的Open-AutoGLM脚本总被拦截?在部署 Open-AutoGLM 脚本时,许多开发者频繁遭遇请求被目标系统拦截的问题。这通常并非脚本逻辑错误所致,而是触发了反爬机制或安全策略。理解拦截背后的原理是优化自动化流程的关键。…

张小明 2025/12/21 16:53:42 网站建设

湖北 商城网站建设多少钱顺义深圳网站建设公司

FaceFusion 人脸替换伦理规范倡议书发布 在数字内容创作迎来爆发式增长的今天,AI生成技术正以前所未有的速度重塑我们对“真实”的认知。尤其是基于深度学习的人脸替换技术,已经从实验室走向大众视野——一段视频中的人物可以被无缝替换成另一个人&#…

张小明 2026/1/1 7:43:46 网站建设

手机网站开发步骤江苏网站建设流程

在使用 Vite 构建的项目中,你可能会注意到一个特殊的隐藏文件夹: node_modules/.vite/deps/这个目录是 Vite 的依赖预构建(Dependency Pre-Bundling)机制的核心产物。它对开发服务器的启动速度、HMR(热更新&#xff09…

张小明 2025/12/23 5:18:37 网站建设