
如何把S3上传URL保存到数据库S3DirectUpload回调机制完整教程【免费下载链接】s3_direct_uploadDirect Upload to Amazon S3 With CORS项目地址: https://gitcode.com/gh_mirrors/s3/s3_direct_upload很多 Rails 开发者在用 s3_direct_upload 实现文件直传 Amazon S3 后都会卡在同一个问题文件确实传上去了但怎么把 S3 上传 URL 保存到数据库本文就以开源项目S3DirectUpload一个基于 CORS 的 Rails 直传 S3 方案为例完整拆解它的回调机制从浏览器直传 S3到服务器收到回调、把上传地址写入数据库的整条链路。看完这篇教程你就能在自己的应用里轻松实现上传即持久化。为什么上传完成后还要把S3上传URL保存到数据库直接上传模式Direct Upload下文件是由浏览器绕过应用服务器、直接发送到 S3的。这样做的好处很明显 应用服务器零带宽压力大文件上传不阻塞 Web 进程 不用在服务器上中转节省流量和磁盘空间⚡ 配合 jQuery-File-Upload支持多文件、带进度条但代价是你的数据库并不知道文件已经存在。用户刷新页面后列表里看不到刚上传的图片因为记录根本没落库。所以把 S3 上传 URL 保存到数据库这一步是直传方案的灵魂——而它正是靠 S3DirectUpload 的回调机制完成的。S3DirectUpload回调机制的工作原理一张图看懂整个流程分四步浏览器直传前端把文件 POST 到 S3附带表单助手生成的 policy 与 signature 签名这段逻辑在 form_helper.rb 中生成S3 返回结果上传成功S3 返回 201 状态码和包含文件地址Location的 XML前端解析 URLJavaScript 从响应中取出完整的 S3 上传 URL见 s3_direct_upload.js.coffee 的build_content_object回调服务器脚本把该 URL 作为参数AJAX POST 到callback_url由你的 Rails 控制器接收并保存到数据库浏览器 ──直传文件──▶ S3返回201文件URL │ └──回调POST(callback_url携带上传URL)──▶ Rails控制器──▶ 写入数据库其中第 4 步就是整个回调机制的核心对应 s3_direct_upload.js.coffee 里的done回调上传一完成前端立刻把content.url塞进参数、发给你的服务器。三步配置S3DirectUpload回调把上传URL写入数据库第一步配置AWS密钥与CORS直传前提先初始化 AWS 凭证参考 config_aws.rb 的配置方式# config/initializers/s3_direct_upload.rb S3DirectUpload.config do |c| c.access_key_id 你的 AccessKeyId c.secret_access_key 你的 SecretAccessKey c.bucket your-bucket c.region nil # 非默认区域需填写如 s3-eu-west-1 end同时务必在 S3 控制台为 Bucket 配置CORS 规则否则浏览器直传会被拦截详细格式见 README.mdCORSConfiguration CORSRule AllowedOriginhttp://localhost:3000/AllowedOrigin AllowedMethodGET/AllowedMethod AllowedMethodPOST/AllowedMethod AllowedMethodPUT/AllowedMethod AllowedHeader*/AllowedHeader /CORSRule /CORSConfiguration⚠️ 生产环境记得把AllowedOrigin换成你的真实域名。第二步在视图中设置callback_url和callback_param这一步是整个回调机制的关键配置。s3_uploader_form表单助手支持两个决定回调行为的参数源码见 form_helper.rb参数作用默认值callback_url上传完成后POST 到哪个服务器地址无不配置则不回调callback_param回调 POST 时携带上传 URL 的参数名filecallback_method回调使用的 HTTP 方法POST看一个把 S3 上传 URL 保存到数据库的标准写法% s3_uploader_form callback_url: photos_url, callback_param: photo[image_url], id: s3-uploader do % % file_field_tag :file, multiple: true, data: { url: s3_uploader_url } % % end %注意callback_param: photo[image_url]的写法——它把 URL 直接映射到模型的image_url字段上服务器收到的参数就是photo[image_url] http://your-bucket.s3.amazonaws.com/uploads/xxx.jpg。然后在application.js.coffee里激活插件jQuery - $(#s3-uploader).S3Uploader()第三步在控制器中保存S3上传URL前端回调 POST 到你指定的callback_url后剩下的就是 Rails 常规操作了——在控制器里把参数写入数据库# app/controllers/photos_controller.rb def create photo Photo.new(photo_params) photo.save end private def photo_params params.permit(:photo [:image_url]) # 关键接收回调带来的 S3 上传 URL end再配合一个返回 JavaScript 的响应模板就能做到无刷新地把新图片追加到页面这是 README 推荐的持久化方案之一%# app/views/photos/create.js.erb % % if photo.new_record? % alert(保存失败% j photo.errors.full_messages.join(, ) %); % else % $(#container).append(% j render(photo) %); % end %回调时除了URL服务器还能拿到什么很多新手不知道回调 POST 到服务器时请求里不只是 URL。查看 s3_direct_upload.js.coffee 的build_content_object会发现它默认携带这些参数url— S3 上的完整文件地址即你要保存的 S3 上传 URLfilename— 原始文件名filepath— 不含域名和文件名的路径filesize— 文件大小filetype— 文件类型如 image/jpeg如果你想把这些信息一并入库只需在模型里加对应字段控制器里一并 permit 即可。另外jQuery 插件还支持additional_data选项可附带自定义参数一起回调。保存URL的进阶玩法回调事件钩子除了依赖callback_url自动回调S3DirectUpload 还提供了几个前端事件钩子适合做更精细的控制比如在 URL 保存前先做校验# 单个文件上传成功此时服务器回调可能还在路上 $(#s3-uploader).bind s3_upload_complete, (e, content) - console.log 上传完成: #{content.url} # 所有文件上传完毕 $(document).bind s3_uploads_complete, - console.log 全部上传完成 # 上传失败 $(#s3-uploader).bind s3_upload_failed, (e, content) - alert #{content.filename} 上传失败#{content.error_thrown}常见问题排查URL保存不上怎么办Q1回调后数据库里没有 URL先检查视图里是否配置了callback_url——README 明确指出不配置callback_url就不会有任何回调。其次确认callback_param与控制器permit的参数名完全一致。Q2浏览器报跨域错误99% 是 S3 的 CORS 规则没配对。核对AllowedOrigin是否包含当前域名、AllowedHeader是否为*。Q3想要 PUT 更新而不是新增记录把表单的callback_method设为PUT并去掉 file_field 的multiple: true即可用回调更新已有模型非常适合头像上传这类场景。Q4上传的 URL 是http://而非https://用s3_uploader_url生成上传地址时默认走 HTTPS见 form_helper.rb确认前端data: { url: s3_uploader_url }没有传false。总结把 S3 上传 URL 保存到数据库本质就是理解并复用S3DirectUpload 的回调机制s3_uploader_form负责声明回调地址与参数名前端脚本在上传成功后自动把 URL 回传服务器你的控制器只需照常接收、落库。三步走——配置 CORS、设置callback_url/callback_param、控制器保存参数——就能让每一次直传都留下数据库记录。想深入研究的同学可以 clone 仓库https://gitcode.com/gh_mirrors/s3/s3_direct_upload查看完整源码重点阅读 app/assets/javascripts/s3_direct_upload.js.coffee 与 lib/s3_direct_upload/form_helper.rb 两个文件回调机制的每一行逻辑都在其中。【免费下载链接】s3_direct_uploadDirect Upload to Amazon S3 With CORS项目地址: https://gitcode.com/gh_mirrors/s3/s3_direct_upload创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考