Gravatar图片存入ActiveStorage遇Net::HTTP问题及解决方法
问题解答
为什么Net::HTTP调用得到302响应?
- 你构造的请求URL里错误混入了curl的
--output参数,这是curl命令的专属选项,不属于URL的一部分,导致请求地址无效,Gravatar服务器返回302跳转。 - curl默认会自动跟随重定向获取最终资源,而
Net::HTTP.get_response默认不会处理302跳转,即使URL正确,也会直接返回跳转响应,不会自动获取图片内容。
正确实现将Gravatar图片存入ActiveStorage的方法
直接使用以下修正后的代码逻辑即可:
if !current_user.user_preference.identicon.present? puts 'identicon absent' # 构造正确的Gravatar请求地址,移除curl专属参数 gravatar_url = "https://www.gravatar.com/avatar/#{current_user.virtual_qr_code}?d=identicon" # 获取图片二进制内容,Net::HTTP.get会自动跟随重定向 image_data = Net::HTTP.get(URI(gravatar_url)) # 将二进制数据包装为StringIO对象,适配ActiveStorage的attach要求 image_io = StringIO.new(image_data) # 附加到ActiveStorage,指定文件名、内容类型 current_user.user_preference.identicon.attach( io: image_io, filename: "#{current_user.id}_avatar.png", content_type: 'image/png' ) end
额外优化建议
- 添加异常处理,避免网络请求失败导致程序崩溃:
begin image_data = Net::HTTP.get(URI(gravatar_url)) # 后续附加逻辑 rescue StandardError => e puts "获取Gravatar图片失败: #{e.message}" end
- 如果需要更精细控制重定向或获取真实的内容类型,可以手动处理响应:
response = Net::HTTP.get_response(URI(gravatar_url)) # 手动跟随所有重定向 while response.is_a?(Net::HTTPRedirection) response = Net::HTTP.get_response(URI(response['location'])) end image_data = response.body content_type = response['content-type'] current_user.user_preference.identicon.attach( io: StringIO.new(image_data), filename: "#{current_user.id}_avatar", content_type: content_type )
内容的提问来源于stack exchange,提问作者Jerome
相关产品推荐
相关产品推荐

