Ruby on rails 使用jQuery文件上载在S3中设置文件内容类型

Ruby on rails 使用jQuery文件上载在S3中设置文件内容类型,ruby-on-rails,amazon-s3,jquery-file-upload,Ruby On Rails,Amazon S3,Jquery File Upload,我需要帮助通过客户端jQuery上传表单向amazon提供内容类型。我需要添加内容类型,因为我上传的音频文件不会在jPlayer for ie10中播放,除非内容类型设置正确。我使用了pjambet的博客文章-来建立和运行优秀的文章顺便说一句。看起来字段的顺序非常重要。我一直在尝试插入一个隐藏的输入标签,要么包含我认为相关的内容类型audio/mpeg3,要么空白,由我的上传脚本填充。不走运。添加额外字段时,上载挂起 direct-upload-form.html.erb <form ac

我需要帮助通过客户端jQuery上传表单向amazon提供内容类型。我需要添加内容类型,因为我上传的音频文件不会在jPlayer for ie10中播放,除非内容类型设置正确。我使用了pjambet的博客文章-来建立和运行优秀的文章顺便说一句。看起来字段的顺序非常重要。我一直在尝试插入一个隐藏的输入标签,要么包含我认为相关的内容类型audio/mpeg3,要么空白,由我的上传脚本填充。不走运。添加额外字段时,上载挂起

direct-upload-form.html.erb

<form accept-charset="UTF-8" action="http://my_bucket.s3.amazonaws.com" class="direct-upload" enctype="multipart/form-data" method="post"><div style="margin:0;padding:0;display:inline"></div>

    <%= hidden_field_tag :key, "${filename}" %>
    <%= hidden_field_tag "AWSAccessKeyId", ENV['AWS_ACCESS_KEY_ID'] %>
    <%= hidden_field_tag :acl, 'public-read' %>
    <%= hidden_field_tag :policy %>
    <%= hidden_field_tag :signature %>
    <%= hidden_field_tag :success_action_status, "201" %>
    <%= file_field_tag :file %>

    <div class="row-fluid">
        <div class="progress hide span8">
            <div class="bar"></div>
        </div>
    </div>

</form>
已签名的\u URL\u controller.rb

class SignedUrlsController < ApplicationController
  def index
    render json: {
      policy: s3_upload_policy_document,
      signature: s3_upload_signature,
      key: "uploads/#{SecureRandom.uuid}/#{params[:doc][:title]}",
      success_action_redirect: "/"
    }
  end

  private

  # generate the policy document that amazon is expecting.
  def s3_upload_policy_document
    Base64.encode64(
      {
        expiration: 30.minutes.from_now.utc.strftime('%Y-%m-%dT%H:%M:%S.000Z'),
        conditions: [
          { bucket: ENV['AWS_S3_BUCKET'] },
          { acl: 'public-read' },
          ["starts-with", "$key", "uploads/"],
          { success_action_status: '201' }
        ]
      }.to_json
    ).gsub(/\n|\r/, '')
  end

  # sign our request by Base64 encoding the policy document.
  def s3_upload_signature
    Base64.encode64(
      OpenSSL::HMAC.digest(
        OpenSSL::Digest::Digest.new('sha1'),
        ENV['AWS_SECRET_ACCESS_KEY'],
        s3_upload_policy_document
      )
    ).gsub(/\n/, '')
  end
end

如上述问题的评论部分所述,为上传到音频/mpeg3的内容设置内容类型需要进行两项更改

必须更改S3 POST API调用的策略以接受附加的内容类型值。在示例代码中,可以通过将以下条件添加到s3_upload_policy_document方法中的条件数组中来实现:[eq,$Content Type,audio/mpeg3]

内容类型变量必须包含在对S3的POST请求中。在jQuery文件上传器插件中,可以通过向发送到S3的表单添加一个隐藏字段来实现这一点,该字段的名称为Content Type,值为audio/mpeg3


如上述问题的评论部分所述,为上传到音频/mpeg3的内容设置内容类型需要进行两项更改

必须更改S3 POST API调用的策略以接受附加的内容类型值。在示例代码中,可以通过将以下条件添加到s3_upload_policy_document方法中的条件数组中来实现:[eq,$Content Type,audio/mpeg3]

内容类型变量必须包含在对S3的POST请求中。在jQuery文件上传器插件中,可以通过向发送到S3的表单添加一个隐藏字段来实现这一点,该字段的名称为Content Type,值为audio/mpeg3


向表单中添加一个名为Content Type的隐藏输入以及一个与文件的MIME类型匹配的值应该可以工作,但是您还需要修改策略your/signed_url脚本以接受您的请求。最好使用Fiddler或Charles等web调试工具来调查发送到S3的实际请求和响应,以便更好地了解发生了什么。有趣的是,我从未想过要更新它。我显然需要在S3上做更多的家庭作业。我在问题中为返回签名的控制器添加了代码。因此,在该控制器中的s3_upload_policy_document方法中,将新字段添加到条件数组中?是的,在条件数组中添加类似[eq,$Content Type,audio/mpeg3]的内容。当S3停止响应时,根据策略,您将知道您做对了:……非常感谢@dcro,这就成功了。并设置上传时的内容类型,使音频可在ie制作时播放!:如果你把你的评论变成一个答案,我很乐意接受。不客气,我很高兴你能让它起作用。我已经添加了上面的信息作为答案。向表单中添加一个名为Content Type的隐藏输入以及一个与文件MIME类型匹配的值应该可以,但是您还需要修改S3的策略/signed_URL脚本以接受您的请求。最好使用Fiddler或Charles等web调试工具来调查发送到S3的实际请求和响应,以便更好地了解发生了什么。有趣的是,我从未想过要更新它。我显然需要在S3上做更多的家庭作业。我在问题中为返回签名的控制器添加了代码。因此,在该控制器中的s3_upload_policy_document方法中,将新字段添加到条件数组中?是的,在条件数组中添加类似[eq,$Content Type,audio/mpeg3]的内容。当S3停止响应时,根据策略,您将知道您做对了:……非常感谢@dcro,这就成功了。并设置上传时的内容类型,使音频可在ie制作时播放!:如果你把你的评论变成一个答案,我很乐意接受。不客气,我很高兴你能让它起作用。我已经添加了上面的信息作为答案。如果内容类型未知怎么办?例如,假设您正在上载具有不同内容类型的多个文件?@Mohamad您可以在策略中使用此条件:[以$content Type开头,]该策略将接受任何内容类型。是的,我终于在文档中找到了它。我使用的是AWS gem,它将密钥映射到与在策略中设置它不同的值。大小写导致策略错误并使我无法使用。如果内容类型未知,该怎么办?例如,假设您正在上载具有不同内容类型的多个文件?@Mohamad您可以在策略中使用此条件:[以$C开头]
内容类型,]可以接受任何内容类型。是的,我终于在文档中找到了它。我使用的是AWS gem,它将密钥映射到与在策略中设置它不同的值。资本化导致了一个政策错误,把我甩了。
class SignedUrlsController < ApplicationController
  def index
    render json: {
      policy: s3_upload_policy_document,
      signature: s3_upload_signature,
      key: "uploads/#{SecureRandom.uuid}/#{params[:doc][:title]}",
      success_action_redirect: "/"
    }
  end

  private

  # generate the policy document that amazon is expecting.
  def s3_upload_policy_document
    Base64.encode64(
      {
        expiration: 30.minutes.from_now.utc.strftime('%Y-%m-%dT%H:%M:%S.000Z'),
        conditions: [
          { bucket: ENV['AWS_S3_BUCKET'] },
          { acl: 'public-read' },
          ["starts-with", "$key", "uploads/"],
          { success_action_status: '201' }
        ]
      }.to_json
    ).gsub(/\n|\r/, '')
  end

  # sign our request by Base64 encoding the policy document.
  def s3_upload_signature
    Base64.encode64(
      OpenSSL::HMAC.digest(
        OpenSSL::Digest::Digest.new('sha1'),
        ENV['AWS_SECRET_ACCESS_KEY'],
        s3_upload_policy_document
      )
    ).gsub(/\n/, '')
  end
end