Rails 7中ActionText/Trix编辑器无法显示S3存储的媒体文件
Rails 7 ActionText 媒体文件无法在S3显示问题
开发Rails 7应用,使用ActionText/Trix编辑器,媒体文件已成功上传至AWS S3,但在Trix编辑器内及页面展示时均无法加载;普通图片/媒体上传至S3则能正常显示,仅ActionText关联的媒体有问题,开发和生产环境均存在此现象。
现有配置
storage.yml
amazon: service: S3 access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> region: eu-north-1 bucket: <app name>-<%= Rails.env %>
credentials.yml
aws: access_key_id: xxx secret_access_key: xxx
视图与模型代码
app/views/active_storage/blobs/_blob.html.erb
<figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>"> <% if blob.image? %> <%= image_tag blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ]) %> <% end %> <% if blob.video? %> <%= video_tag url_for(blob.attachable), preload: "auto", ... %> <% end %> <% if blob.audio? %> <%= audio_tag url_for(blob.attachable), controls: "controls" %> <% end %> <figcaption class="attachment__caption"> <% if caption = blob.try(:caption) %> <%= caption %> <% end %> </figcaption> </figure>
表单渲染代码
<%= rich_content_form.rich_text_area :content %> <%= rich_content_form.hidden_field :id if rich_content_form.object.persisted? %>
模型配置
has_rich_text :content
控制台报错信息
Safari 报错
[Error] Failed to load resource: Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin. Status code: 200 (bo2qo7q0diw0juxl9v85y63nv771, line 0) [Error] XMLHttpRequest cannot load https://<bucket-name>.s3.eu-north-1.amazonaws.com/bo2qo7q0diw0juxl9v85y63nv771?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAUP7MDHHNOBYGZXSA%2F20230731%2Feu-north-1%2Fs3%2Faws4_request&X-Amz-Date=20230731T103209Z&X-Amz-Expires=300&X-Amz-SignedHeaders=content-length%3Bcontent-md5%3Bcontent-type%3Bhost&X-Amz-Signature=a0f1b1cc9be7cf2a4618095379fda05bde5418707c280ca2473cad6046d6a671 due to access control checks. [Error] Error: Direct upload failed: Error storing "grooveland-designs-8kkTIumkHxU-unsplash.jpg". Status: 0 nrWrapper (860.03a8b7a5-1.236.0.min.js:1:6259)
Chrome 报错
edit:1 Access to XMLHttpRequest at 'https://<bucket-name>.s3.eu-north-1.amazonaws.com/qkqx3qd8gq9a4uogojg8dvh3vyvu?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAUP7MDHHNOBYGZXSA%2F20230731%2Feu-north-1%2Fs3%2Faws4_request&X-Amz-Date=20230731T104633Z&X-Amz-Expires=300&X-Amz-SignedHeaders=content-length%3Bcontent-md5%3Bcontent-type%3Bhost&X-Amz-Signature=5c68bee1732d950470c0fccc203a5f8d3895bd7122f3e4667ca82ee63210242f' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. 860.03a8b7a5-1.236.0.min.js:1 Uncaught Error: Direct upload failed: Error storing "grooveland-designs-8kkTIumkHxU-unsplash.jpg". Status: 0 at AttachmentUpload.directUploadDidComplete (actiontext-28c61f5197c204db043317a8f8826a87ab31495b741f854d307ca36122deefce.js:849:13) at BlobUpload.callback (actiontext-28c61f5197c204db043317a8f8826a87ab31495b741f854d307ca36122deefce.js:624:17) at BlobUpload.requestDidError (actiontext-28c61f5197c204db043317a8f8826a87ab31495b741f854d307ca36122deefce.js:597:12) at XMLHttpRequest.<anonymous> (actiontext-28c61f5197c204db043317a8f8826a87ab31495b741f854d307ca36122deefce.js:582:57) at XMLHttpRequest.nrWrapper (860.03a8b7a5-1.236.0.min.js:1:6208) directUploadDidComplete @ actiontext-28c61f5197c204db043317a8f8826a87ab31495b741f854d307ca36122deefce.js:849 (anonymous) @ actiontext-28c61f5197c204db043317a8f8826a87ab31495b741f854d307ca36122deefce.js:624 requestDidError @ actiontext-28c61f5197c204db043317a8f8826a87ab31495b741f854d307ca36122deefce.js:597 [...] actiontext-28c61f5197c204db043317a8f8826a87ab31495b741f854d307ca36122deefce.js:586 PUT https://<bucket-name>.s3.eu-north-1.amazonaws.com/qkqx3qd8gq9a4uogojg8dvh3vyvu?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAUP7MDHHNOBYGZXSA%2F20230731%2Feu-north-1%2Fs3%2Faws4_request&X-Amz-Date=20230731T104633Z&X-Amz-Expires=300&X-Amz-SignedHeaders=content-length%3Bcontent-md5%3Bcontent-type%3Bhost&X-Amz-Signature=5c68bee1732d950470c0fccc203a5f8d3895bd7122f3e4667ca82ee63210242f net::ERR_FAILED
解决思路
配置S3 Bucket CORS规则
报错明确显示跨域请求被阻止,需在AWS S3控制台为目标Bucket配置CORS策略,允许你的应用域名(开发环境是http://localhost:3000,生产环境是正式域名)发起跨域请求。示例CORS配置:[ { "AllowedHeaders": ["*"], "AllowedMethods": ["GET", "PUT", "POST", "DELETE"], "AllowedOrigins": ["http://localhost:3000", "https://your-production-domain.com"], "ExposeHeaders": ["ETag"] } ]注意:
AllowedOrigins需根据实际环境调整,生产环境避免直接用*,开发环境可暂时用*测试。确认Active Storage的上传选项
在config/storage.yml的amazon配置中添加public: true(如果需要公开访问),确保上传文件的ACL设置为public-read;若使用私有Bucket,需确保生成的签名URL包含正确的CORS头且有效期足够。验证Direct Upload配置
确保环境配置文件(config/environments/development.rb、production.rb)中启用了正确的存储服务:config.active_storage.service = :amazon同时确认
config/importmap.rb中已引入ActionText依赖:pin "@rails/actiontext",保证直接上传的JS功能正常加载。
内容的提问来源于stack exchange,提问作者Anders
相关产品推荐
相关产品推荐

