Подтвердить что ты не робот

Rails: загрузка dropzone, S3, несущая, не работающая в Safari, но работающая в Google Chrome

Я использую dropzone с S3 и несущей. Я могу загружать изображения через Google Chrome, но я не могу заставить его работать с 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
    }
  };
}

EDIT: Текущая конфигурация 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>

Протестировано и не работает

EDIT: У меня также есть прямая загрузка 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
4b9b3361

Ответ 1

Недавно я столкнулся с подобной проблемой с Safari и обнаружил, что он отправляет дополнительный заголовок Access-Control-Request, который не содержит Chrome, в частности "origin". Чтобы устранить эту разницу, мне нужно было обновить конфигурацию AWS CORS в целевом ковше.

Документация AWS о необходимости заголовков запросов, соответствующих разрешенной конфигурации заголовка. Третий маркер указывает на это требование:

Каждый заголовок, указанный в заголовке запроса Access-Control-Request-Headers в предпродажном запросе, должен соответствовать элементу AllowedHeader.

fooobar.com/info/155938/... дает пример config:

<?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>