Rails:上传dropzone,S3,carrierwave,不适用于Safari,但适用于Google Chrome

Rails: Uploading dropzone, S3, carrierwave, not working in Safari, but works in Google Chrome

本文关键字:适用于 Safari Chrome Google 不适用 carrierwave 上传 dropzone S3 Rails      更新时间:2023-09-26

我将dropzone与S3和carrierwave一起使用。我可以通过谷歌浏览器上传图像,但我无法使用Safari,这很奇怪。

这是我的表格

= nested_form_for @trip, html: { multipart: true, id: 'fileupload', class: 'directUpload', data: { 'form-data' => (@s3_direct_post.fields), 'url' => @s3_direct_post.url, 'host' => URI.parse(@s3_direct_post.url).host } } do |f|
  .dropzone#imageUpload
    = f.simple_fields_for :trip_images, TripImage.new, child_index: TripImage.new.object_id do |ff|
    = ff.file_field :photo, class: 'hide form-fields'
    = f.button :submit, id: "submit-data"

这在跳闸控制器中

def set_s3_direct_post
  @s3_direct_post = S3_BUCKET.presigned_post(key: "/uploads/temporary/#{SecureRandom.uuid}/${filename}", success_action_status: '201', acl: 'public-read', content_type: 'image/jpeg')
end

这是TripImage型号

class TripImage < ActiveRecord::Base
  belongs_to :resource, :polymorphic => true
  mount_uploader :photo, PhotoUploader
  after_create :process_async
  def to_jq_upload
    {
      'name' => read_attribute(:attachment_file_name),
      'size' => read_attribute(:attachment_file_size),
      'url' => attachment.url(:original),
      'thumbnail_url' => attachment.url(:thumb),
      'delete_url' => "/photos/#{id}",
      'delete_type' => 'DELETE'
    }
  end
  private
  def process_async
    PhotoVersioningJob.set( wait: 5.seconds ).perform_later(self.id)
  end
end

这是js

$(function(){
  $('.directUpload').find(".dropzone").each(function(i, elem) {
    s3ImageUpload(elem);
  });
})
function s3ImageUpload(elem){
  var fileInput    = $(elem);
  var form         = $(fileInput.parents('form:first'));
  var form_url = form.data('url');
  var form_data = form.data('form-data');
  Dropzone.options.imageUpload = {
    url: form_url,
    params: form_data,
    uploadMultiple: false,
    addRemoveLinks: true,
    removedfile: function(file){
      //some codes
    },
    success: function(file, serverResponse, event){
      //some codes
    },
    error: function(data){
      //some codes
    }
  };
}

编辑:当前CORS配置

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*.example.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
        <AllowedHeader>origin</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

已测试但不起作用

编辑:我也有S3直接上传,不确定这是否也会影响它?

S3DirectUpload.config do |c|
  c.access_key_id = Rails::AWS.config['access_key_id']       # your access key id
  c.secret_access_key = Rails::AWS.config['secret_access_key']   # your secret access key
  c.bucket = Rails::AWS.config['bucket_name']              # your bucket name
  c.region = 's3'             # region prefix of your bucket url. This is _required_ for the non-default AWS region, eg. "s3-eu-west-1"
end

我最近在Safari上遇到了类似的问题,发现它发送了一个Chrome没有的额外访问控制请求头,特别是"origin"。为了解决这个差异,我需要更新目标bucket上的AWS CORS配置。

AWS关于请求标头与允许的标头配置匹配的必要性的文档。第三个要点明确了这一要求:

飞行前请求的访问控制请求标头中列出的每个标头都必须与AllowedHeader元素匹配。

这个有用的StackOverflow答案给出了一个配置示例:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
    <AllowedHeader>x-requested-with</AllowedHeader>
  </CORSRule>
</CORSConfiguration>

需要添加哪些内容才能在Safari中运行:

    <AllowedHeader>origin</AllowedHeader>