Rails:上传dropzone,S3,carrierwave,无法在Safari中运行,但适用于Google Chrome

hel*_*llo 13 javascript ruby-on-rails amazon-s3 carrierwave dropzone.js

我正在使用带有S3和载波的dropzone.我可以通过谷歌浏览器上传图片,但我无法使用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"
Run Code Online (Sandbox Code Playgroud)

这是在Trip控制器中

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
Run Code Online (Sandbox Code Playgroud)

这是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
Run Code Online (Sandbox Code Playgroud)

这是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
    }
  };
}
Run Code Online (Sandbox Code Playgroud)

编辑:当前的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>
Run Code Online (Sandbox Code Playgroud)

经过测试,不起作用

编辑:我也有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
Run Code Online (Sandbox Code Playgroud)

cra*_*gts 6

我最近遇到了与Safari类似的问题,并发现它正在发送一个Chrome没有的额外的Access-Control-Request-Header - 特别是'origin'.为了解决这种差异,我需要更新目标存储桶上的AWS CORS配置.

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

预检请求中请求的Access-Control-Request-Headers标头中列出的每个标头必须与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>
Run Code Online (Sandbox Code Playgroud)

需要添加什么才能让它在Safari中运行:

    <AllowedHeader>origin</AllowedHeader>
Run Code Online (Sandbox Code Playgroud)