ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

源码解析:S3DirectUpload 前端 CoffeeScript 是如何工作的?

源码解析:S3DirectUpload 前端 CoffeeScript 是如何工作的? 源码解析S3DirectUpload 前端 CoffeeScript 是如何工作的【免费下载链接】s3_direct_uploadDirect Upload to Amazon S3 With CORS项目地址: https://gitcode.com/gh_mirrors/s3/s3_direct_uploadS3DirectUpload 是一个借助 CORS 实现直接上传到 Amazon S3的 Rails gem它的灵魂是一段由CoffeeScript编写的前端 jQuery 插件源码。本文将逐行拆解这份源码带你搞懂浏览器绕过服务器、把文件直传 S3的完整机制包括上传流程、进度条刷新、key 占位符替换等核心细节非常适合想看懂 S3 直传原理的新手。一、先认识主角前端插件源码长什么样整个前端逻辑全部集中在一个文件里app/assets/javascripts/s3_direct_upload.js.coffee。它通过# require jquery-fileupload/basic引入了 jQuery File Upload 插件然后对外暴露一个标准的 jQuery 插件方法$.fn.S3Uploader (options) -这意味着你在页面里可以这样调用$(#s3-uploader).S3Uploader()插件还贴心地做了多元素支持如果选择器命中了多个表单length 1它会用each逐个初始化互不干扰。 相关文件app/assets/javascripts/s3_direct_upload.js.coffee、app/assets/stylesheets/s3_direct_upload_progress_bars.css.scss二、上传前的准备Ruby 端如何发号施令直传 S3 的关键前提是安全策略。服务端不负责传输文件但必须签发准入凭证。lib/s3_direct_upload/form_helper.rb中的s3_uploader_form会为表单生成一批隐藏字段包括字段作用key文件在 S3 上的存储路径模板policyBase64 编码的上传策略 JSONsignature用密钥对 policy 做的 HMAC-SHA1 签名AWSAccessKeyIdAWS 访问密钥 IDacl文件权限默认 public-readsuccess_action_status上传成功后返回 201 状态码前端源码正是读取这些隐藏字段拼出符合 S3 要求的 POST 请求。formData回调里的这段代码就是核心key $uploadForm.data(key) .replace({timestamp}, new Date().getTime()) .replace({unique_id}, files[0].unique_id)三、核心流程拆解一次文件上传的生命周期jQuery File Upload 会按顺序触发几个回调S3DirectUpload 的源码把它们组织成了一条清晰的流水线回调触发时机源码做了什么add选中文件生成unique_id、执行before_add校验、渲染进度条start开始上传触发s3_uploads_start事件progress上传中按已加载比例刷新进度条宽度done上传成功解析 S3 返回的 URL、可选回传服务器fail上传失败组装错误信息、触发s3_upload_failed两个值得注意的细节unique_id如何生成源码用Math.random().toString(36).substr(2,16)生成一段随机字符串专门用来避免同名文件比如手机里全是image.jpg在 S3 上互相覆盖。before_add是拦截器。你可以传入一个返回布尔值的函数返回false就取消该文件上传常用于文件名校验。四、进度条是如何实时刷新的进度条的秘密藏在progress回调里代码极简progress: (e, data) - if data.context progress parseInt(data.loaded / data.total * 100, 10) data.context.find(.bar).css(width, progress %)每次浏览器报告上传进度就把.bar元素的宽度改成对应的百分比。进度条外观由s3_direct_upload_progress_bars.css.scss定义灰色边框 绿色填充条400px 宽上传完成后默认自动移除可通过remove_completed_progress_bar: false保留。进度条模板来自页面里的template-upload脚本标签源码会用它渲染出带unique_id的进度条容器再插入到表单或progress_bar_target指定的位置。五、key 占位符替换机制文件最终存到哪里S3 上的存储路径由key模板决定默认长这样uploads/{timestamp}-{unique_id}-随机值/${filename}前端源码在formData回调里依次替换四个占位符{timestamp}→ 当前毫秒时间戳保证唯一性{unique_id}→ 随机字符串防止同名冲突{cleaned_filename}→ 清洗后的文件名{extension}→ 文件扩展名其中cleaned_filename函数负责把文件名里的空格换成下划线、剔除特殊字符cleaned_filename (filename) - filename.replace(/\s/g, _).replace(/[^\w.-]/gi, ) 顺带一提源码还专门处理了IE 9 及以下的兼容——它们没有 XHR2/FormData只能退化为普通表单提交所以会直接改写隐藏的key输入框值。六、上传完成后content 对象与事件钩子上传成功后build_content_object会从 S3 返回的 XML 响应里解析出Location节点得到文件的完整 URL并附带文件名、大小、类型等信息content.url $(result).find(Location).text()拿到content后插件会触发一系列事件钩子方便你在业务代码里监听s3_upload_complete—— 单个文件上传成功可拿到content.url填入隐藏字段s3_uploads_complete—— 整批文件全部完成s3_upload_failed—— 上传失败附带error_thrown错误信息ajax:success等 —— 服务器回调callback_url完成后触发如果配置了callback_url插件还会自动把 S3 URL 通过 AJAX POST 回 Rails 服务器实现上传完立刻通知后端持久化。七、公开方法与高级定制源码最后暴露了三个公开方法可随时修改行为方法作用initialize()保存 key、初始化上传逻辑构造时自动调用path(new_path)动态修改 S3 存储路径additional_data(data)动态追加回传服务器的附加数据其他常用配置项包括path、before_add、progress_bar_target、click_submit_target、allow_multiple_files等都可以在S3Uploader()调用时通过 options 传入配置合并逻辑在源码开头用$.extend settings, options完成。八、总结一张图看懂直传流程用户选择文件 │ ▼ add 回调 → 生成 unique_id → before_add 校验 │ ▼ 渲染进度条 → data.submit() 提交到 S3CORS 直传 │ ▼ progress 回调 → 实时刷新进度条宽度 │ ▼ done 回调 → 解析 XML 得 URL → 可选回调 Rails 服务器 │ ▼ 触发 s3_upload_complete / s3_uploads_complete 事件一句话概括Ruby 端负责签发策略与签名CoffeeScript 前端负责执行上传与交互服务器全程不碰文件内容这也是直传能大幅节省带宽的根本原因。想亲手调试这份源码核心逻辑都在app/assets/javascripts/s3_direct_upload.js.coffee这一个文件里配合lib/s3_direct_upload/form_helper.rb一起阅读你就能彻底掌握 S3DirectUpload 的前端工作原理了。【免费下载链接】s3_direct_uploadDirect Upload to Amazon S3 With CORS项目地址: https://gitcode.com/gh_mirrors/s3/s3_direct_upload创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表