使用 CarrierWave 通过 AWS S3上传文件到阿里云 OSS

虽然阿里云 OSS 与 AWS S3 兼容,但需要使用阿里云的特定端点进行配置。CarrierWave 是一个流行的 Ruby 文件上传库,可以方便地与 AWS S3 集成。以下是配置和使用方法:

1. 安装必要的 gem

首先,在 Gemfile 中添加以下 gem:

gem 'carrierwave'
gem 'aws-sdk-s3' 

然后运行 bundle install

2. 配置 CarrierWave

创建上传器

运行生成器创建上传器:

rails generate uploader Avatar

配置 AWS S3

在 config/initializers/carrierwave.rb 中添加以下配置:

CarrierWave.configure do |config|  config.fog_credentials = {provider:              'AWS',                        # 必填aws_access_key_id:     ENV['AWS_ACCESS_KEY_ID'],     # 推荐使用环境变量aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'], # 推荐使用环境变量region:                'cn-hangzhou',                # 如 'us-east-1'host:                  ENV['AWS_HOST'],              # 可选,自定义端点endpoint:              ENV['AWS_ENDPOINT'],         # 可选,用于兼容S3的服务path_style:            false,                        # 设为 false 使用虚拟托管式访问aws_signature_version: 4}config.fog_directory  = ENV['AWS_BUCKET']             # 存储桶名称config.fog_public     = false                         # 默认文件权限config.fog_attributes = { 'Cache-Control' => "max-age=#{365.day.to_i}" }# 可选:使用存储桶的子目录config.fog_path_prefix = "uploads"
end

3. 在模型中使用上传器

假设你有一个 User 模型需要上传头像:

class User < ApplicationRecordmount_uploader :avatar, AvatarUploader
end

4. 上传器配置示例

在 app/uploaders/avatar_uploader.rb 中:

class AvatarUploader < CarrierWave::Uploader::Base# 选择存储类型storage :fog  # 使用 AWS S3# 覆盖存储目录def store_dir"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"end# 添加白名单扩展名def extension_whitelist%w(jpg jpeg gif png)end# 覆盖文件名def filename"#{secure_token}.#{file.extension}" if original_filename.present?endprotecteddef secure_tokenvar = :"@#{mounted_as}_secure_token"model.instance_variable_get(var) || model.instance_variable_set(var, SecureRandom.uuid)end
end

5. 在视图中使用

表单中使用文件字段:

<%= form_for @user do |f| %><%= f.file_field :avatar %><%= f.submit %>
<% end %>

显示上传的文件:

<%= image_tag @user.avatar.url if @user.avatar? %>

6. 处理大文件

对于大文件上传,你可能需要:

# 在 config/initializers/carrierwave.rb 中
config.fog_attributes = {'x-amz-meta-uploaded-by' => 'my-app','Cache-Control' => 'max-age=315576000'
}

7. 测试环境配置

在测试环境中,你可能想使用本地存储:

# config/environments/test.rb
config.carrierwave.storage = :file
config.carrierwave.enable_processing = false

 

解决 AWS SDK 上传到阿里云 OSS 的 403 Forbidden 错误

你遇到的 SignatureDoesNotMatch 错误表明 AWS SDK 生成的签名与阿里云 OSS 期望的签名不匹配。这是使用 AWS SDK 访问阿里云 OSS 时的常见问题,因为阿里云 OSS 虽然兼容 S3 协议,但在签名计算上有一些差异。

增加 CarrierWave 配置

# 在 config/initializers/carrierwave.rb 中
config.fog_credentials = {#...path_style:            true,  # 注意这里是 path_style 而不是 force_path_styleaws_signature_version: 4      # 注意参数名是 aws_signature_version 而不是 signature_version
}

但是还是不能完美解决阿里云 OSS 的 SignatureDoesNotMatch 问题。

当您在 CarrierWave 配置中添加:

aws_signature_version: 4

时,fog-aws 内部仍然会强制使用 service: 's3',这就是导致签名不匹配的根本原因。

解决方案:

如果您必须使用 fog-aws,可以通过猴子补丁修改:

# 在 config/initializers/carrierwave.rb 中添加以下补丁
module Fogmodule AWSclass SignatureV4# 重写初始化方法,强制指定service为'oss'def initialize(aws_access_key_id, secret_key, region, service)@region = region@service = 'oss'  # 强制覆盖为oss,原参数service被忽略@aws_access_key_id = aws_access_key_id@hmac = Fog::HMAC.new('sha256', 'AWS4' + secret_key)endendend
end

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/79058.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/79058.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

上位机知识篇---流水线执行

文章目录 前言前言 本文简单介绍了流水线. 基本概念 流水线(Pipeline) 是一种通过将任务分解为多个子任务(阶段),并让不同子任务并行执行以提高效率的技术。其灵感来源于工业流水线,每个阶段专注于特定操作,多任务在不同阶段重叠执行,从而提升整体吞吐率(Throughput)…

第三部分:赋予网页灵魂 —— JavaScript(下)

目录 7 DOM 操作&#xff1a;控制网页的"智能面板7.1 小例子&#xff1a;点击按钮时改变段落文字&#xff0c;根据用户输入改变图片7.2 练习&#xff1a;实现一个简单的 Tab 切换效果 8 事件处理&#xff1a;响应用户的"指令"8.1 小例子&#xff1a;实现点击按钮…

芯片软错误概率探究:基于汽车芯片安全设计视角

摘要&#xff1a; 本文深入剖析了芯片软错误概率问题&#xff0c;结合 AEC-Q100 与 IEC61508 标准&#xff0c;以 130 纳米工艺 1Mbit RAM 芯片为例阐述其软错误概率&#xff0c;探讨汽车芯片安全等级划分及软错误对汽车关键系统的影响&#xff0c;分析先进工艺下软错误变化趋势…

嵌入式AI还是一片蓝海

发现其实还是挺多人关注嵌入式和人工智能交叉领域的&#xff0c;随便一个问题&#xff0c;浏览量就27万了&#xff0c;但是这方面的内容确实少得可怜……所以干脆我自己来补点干货。 推荐一本最近很热门的新书——《边缘人工智能&#xff1a;用嵌入式机器学习解决现实问题》。 …

Linux 怎么安装 Oracle Java 8

在 Linux 系统上安装 Oracle Java 8 的步骤如下&#xff1a; 1. 下载 Oracle Java 8 访问 Oracle 官方网站的 Java 下载页面&#xff1a; 下载链接&#xff1a;Oracle Java 8 下载页面选择适合 Linux x64 的安装包&#xff08;通常是 .tar.gz 格式&#xff09;。需要登录 Or…

nginx配置集群服务器中的tcp负载均衡器

文章目录 前言1. Ubuntu下nginx安装2. nginx的tcp负载配置 前言 假设一台机器支持两万的并发量&#xff0c;现在我们需要保证八万的并发量。首先想到的是升级服务器的配置&#xff0c;比如提高 CPU 执行频率&#xff0c;加大内存等提高机器的物理性能来解决此问题。但是单台机…

【音视频】RTMP流媒体服务器搭建、推流拉流

服务器&#xff1a;SRS(Simple RTMP Server&#xff0c;⽀持RTMP、HTTP-FLV&#xff0c;HLS) 推流端&#xff1a;ffmpeg OBS 拉流端&#xff1a;ffplay VLC srs播放器 1 安装和测试srs流媒体服务器 1.1 安装srs流媒体服务器 srs官⽹&#xff1a;https://github.com/ossrs/…

数据治理与数据管理:定义之辩和责任外包的边界

数据治理与数据管理&#xff1a;定义之辩和责任外包的边界 最近&#xff0c;在数据领域的技术交流中&#xff0c;一位朋友探讨了两个很有意思的问题。这两个问题非常典型&#xff0c;也反映了大家在实际工作和学习中常会遇到的困惑&#xff1a;一是关于“数据管理”和“数据治…

Linux 命令如何同时支持文件参数与管道输入?

文章目录 Linux 命令如何同时支持文件参数与管道输入&#xff1f;命令输入方式与管道机制概述常见输入控制方式常见使用示例程序实现思路&#xff1a;统一处理输入的方式判定输入来源的基本模式为何命令应支持参数与标准输入&#xff1f; GNU Coreutils wc 源码解析&#xff1a…

flutter开发音乐APP(简单的音乐播放demo)

效果如下&#xff1a; 音乐播放界面 锁屏音乐播放展示 主要使用的插件如下 just_audio : 是一个功能丰富的音频播放器&#xff0c;适用于Android、iOS、macOS、Web、Linux和Windows平台。它提供了多种功能&#xff0c;包括从URL、文件、资产或字节流读取音频&#xff0c;支持D…

css中盒模型有哪些

标准盒模型&#xff08;w3c盒模型&#xff09; 在标准盒模型中&#xff0c;元素的width和height只包括内容区域&#xff0c;不包括内边距、边框、外边距。也就是元素的实际宽高是内容区域加上内边距、边框、外边距。 例如&#xff1a;一个元素的宽度设置为100px&#xff0c;内…

第3篇:请求参数处理与数据校验

在 Web 开发中&#xff0c;请求参数处理与数据校验是保障系统稳定性的第一道防线。本文将深入探讨 Egg.js 框架中参数处理的完整解决方案&#xff0c;涵盖常规参数获取、高效校验方案、文件流处理等核心功能&#xff0c;并分享企业级项目中的最佳实践。 一、多场景参数获取策略…

2025年-redis(p1-p10)

1.redis介绍 &#xff08;1&#xff09;基础&#xff1a;常见的数据结构及命令、jedis的应用和优化、springDataRedis的应用和优化 &#xff08;2&#xff09;企业实战的应用场景&#xff1a;共享session、缓存解决问题、秒杀中的redis应用、社交app中的redis应用、redis特殊结…

【AI模型学习】GPT——从v1到v3

文章目录 GPT-1GPT vs BERTGPT-2GPT-3Ai代码 GPT-1 GPT-1&#xff08;Generative Pretrained Transformer 1&#xff09;是 OpenAI 在2018年发布的第一个大规模预训练生成模型。它开创了基于 Transformer 的 预训练-微调 (pretraining-finetuning) 框架&#xff0c;在自然语言…

数字智慧方案6178丨智慧医院医疗信息化建设之以评促建(61页PPT)(文末有下载方式)

资料解读&#xff1a;智慧医院医疗信息化建设之以评促建 详细资料请看本解读文章的最后内容。 在当今数字化时代&#xff0c;医疗行业正经历着深刻变革&#xff0c;智慧医院的建设成为提升医疗服务质量、优化医疗资源配置的关键所在。这份智慧医院医疗信息化建设之以评促建的资…

浅谈C# record关键字

环境:.net8控制台 init关键字 通常我们会有一个常见的需求就是需要实现一个实例化后不可变的类型. 我通常会如下实现,将类的属性的set设为私有,这样只能使用构造函数来实例一个不可变对象. 但是如果内部再声明一个public的方法还是有可能会将我这个对象改变. internal class…

实时数仓dim层设计的一些疑惑点

0.dim层组件的选择 dim层存储要求&#xff1a;需要满足永久存储&#xff08;需要长期保存历史数据&#xff09;和支持根据主键查询单条数据明细&#xff0c;所以排除Kafka&#xff08;时效短&#xff09;&#xff1b; 候选框架&#xff1a;MySQL、Redis、Hive、Doris、HBase …

模型之FIM(Fill-In-the-Middle)补全

文章目录 模型之FIM(Fill-In-the-Middle)补全什么是FIM(Fill-In-the-Middle)FIM 的工作原理FIM 示例:代码补全场景常见模型fim 测试deepseek fim阿里completions 接口要判断模型是否支持特定的特殊标记**1. 模型可以自动推断生成区域****2. `suffix` 是可选的****3. 模型的…

使用CubeMX新建DMA工程——存储器到外设模式

目录 1、新建板级支持包 1、usart.c: 2、修改的地方&#xff1a;在usart.c中添加了这些 3、usart.h: 4、在usart.h中添加了这些&#xff1a; 5、dma.c: 6、dma.h: 2、修改main.c文件 1、在main.c文件中添加头文件 2、添加外部变量声明 3、添加简单延时函数 4、添加…

el-transfer穿梭框数据量过大的解决方案

一&#xff1a;背景 我们这个穿梭框获取的是项目的全量数据&#xff0c;在左边大概有5000条&#xff0c;自己测试了一下5000条数据的效果&#xff0c;发现异常的卡顿&#xff0c;本来打算像el-select一样去解决的&#xff08;只显示一部分&#xff0c;在搜索的时候去全量搜索&a…