【问题标题】:Error http 422 with DirectUpload / ActiveStorage / RailsDirectUpload / ActiveStorage / Rails 出现错误 http 422
【发布时间】:2020-07-21 23:23:06
【问题描述】:

我尝试通过 DirectUpload / ActiveStorage / Rails 6 添加一些带有 ajax 的图像。 我使用 ActiveStorage 支持的先决条件,以便将 DirectUpload 与 Jquery 一起使用: https://edgeguides.rubyonrails.org/active_storage_overview.html#integrating-with-libraries-or-frameworks

const upload = new DirectUpload(file, url)

  upload.create((error, blob) => {
    if (error) {
      // Handle the error
    } else {
      // Add an appropriately-named hidden input to the form with a
      [..]
      console.log(blob.key);
    }
  })

在我的主机上,它适用于所有文件。但是当我尝试将我的应用程序发布到我的主机时,在 DirectUpload 的请求之后,某些文件总是出现错误:

Completed 422 Unprocessable Entity in 2ms (ActiveRecord: 0.0ms | Allocations: 689)

我在我的 webtools 浏览器中查看了 XHR 请求,但有效负载在一个有效的文件和另一个失败的文件中似乎相同:

{id: 219, key: "v2v1aqlk8gyygcc4smjeh0bbuc59", filename: "groupama logo.jpeg",…}
id: 219
key: "v2v1aqlk8gyygcc4smjeh0bbuc59" 
filename: "logo.jpeg" 
content_type: "image/jpeg" 
metadata: {}
byte_size: 17805
checksum: "3GIVi2kNKClfH+d9HGYOfkA==" 
created_at: "2020-04-09T08:25:40.000+02:00" 
signed_id: "eyJfcmFpbHMiOnsibWVzc2zaFnZSI6IkJBaHBBZHM9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--7c0750cb8c86a955a04fa9a11dc5389cdeb5e7b0" 
attachable_sgid: "BAh7CEkiCGdpZAY6BkVUSSIxsaZ2lkOi8vYXBwL0FjdGl2ZVN0b3JhZ2U6OkJsb2IvMjE5P2V4cGlyZXNfaW4GOwBUSSIMcHVycG9zZQY7AFRJIg9hdHRhY2hhYmxlBjsAVEkiD2V4cGlyZXNfYXQGOwBUMA==--64a945c38dc5d85c05156da50b9c38819b106e10" 
direct_upload: {,…}
url: "http://localhost:8491/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSWhkakoyTVdGeGJHczRaM2w1WjJOak5ITnRhbVZvTUdKaWRXTTFPUVk2QmtWVU9oRmpiMjaUwWlc1MFgzUjVjR1ZKSWc5cGJXRm5aUzlxY0dWbkJqc0dWRG9UWTI5dWRHVnVkRjlzWlc1bmRHaHBBbzFGT2cxamFHVmphM04xYlVraUhUTkhTVlpwTW10T1MwTnNaa2dyT1VoSFdVOW1hMEU5UFFZN0JsUT0iLCJleHAiOiIyMDIwLTA0LTA5VDA2OjMwOjQwLjg5NFoiLCJwdXIiOiJibG9iX3Rva2VuIn19--a2acedc0924f735c5cc08db8c4b76f76accc3c8d" 
headers: {Content-Type: "image/jpeg"}

我尝试了这个解决方案,猴子补丁对我不起作用,另一个解决方案似乎不起作用: Rails API ActiveStorage DirectUpload produce 422 Error InvalidAuthenticityToken

我注意到,当我尝试在不使用 DirectUpdate 的情况下将徽标图像文件上传到输入文件时,该文件已正确发送到我的服务器。

= f.file_field :logos, direct_upload: true

你有什么想法要测试吗?

【问题讨论】:

  • 事实上,当我尝试通过 ajax 中的 DirectUpload 上传时,问题似乎与图像的大小有关。一旦尺寸图像超过18ko,上传就会出错。当我使用 ActiveText 并尝试粘贴新图像时,我遇到了同样的错误。
  • 我的主机使用 uwsgi 和 rack 来提供 ror 网站。

标签: rails-activestorage ruby-on-rails-6


【解决方案1】:

我的问题在于用于复制文件的 IO。在ActiveStorage::DiskController#update 中,Rails 使用request.bodyIO.CopyStream 创建文件,并完成校验和文件以验证创建的文件。 并且检查失败并抛出 422 http 错误。

我注意到,在开发模式下,IO 流是String_IO,而在我的主机上,IO 是Uswgi_IO。因为我的主机使用 Uswgi 交付 ruby​​ on rails 应用程序。 uwsgi_io 不包含 length 或 size 方法,当 ActiveStorage 使用这个 IO 创建文件时,文件的大小很奇怪。奇怪的太大了。

我注意到如果RAW_POST_DATA 被分配,那么request.body 返回String_IO。并进入request.raw_post方法,直接用request.content_length读取正文:

raw_post_body.read(content_length)

https://api.rubyonrails.org/classes/ActionDispatch/Request.html#method-i-body

我创建了一个继承ActiveStorage::DiskController 的新控制器,以便在Disk#update 操作之前分配RAW_POST_DATA

class UploadController < ActiveStorage::DiskController

  def update
    request.env['RAW_POST_DATA'] = request.body.read(request.content_length)    
    super
  end
end

之后,我覆盖了我的 ActiveStorage disk#update 路由:

put '/rails/active_storage/disk/:encoded_token', to: 'upload#update

它有效!

ActionText 与 ActiveStorage 一起使用来存储图像,我在图像太大时遇到了同样的问题。 我的补丁也允许在我的主机上制作 ActionText。

【讨论】:

    【解决方案2】:

    感谢您在这里找到罪魁祸首,我在 uwsgi 设置上遇到了完全相同的问题,当我找到您的帖子时,我试图弄清楚为什么内容长度不同。感谢分享!

    我只是采取了一种稍微不同的方法来修复,因为我不想破解 AS 路由,所以我使用以下代码创建了一个 config/initializers 文件:

    Rails.configuration.to_prepare do
      ActiveStorage::DiskController.class_eval do
        before_action :set_raw_post_data, only: :update
    
        def set_raw_post_data
          request.env['RAW_POST_DATA'] = request.body.read(request.content_length)
        end
      end
    end
    

    也许值得在https://github.com/unbit/uwsgi 中创建一个问题让他们知道这一点?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-04
      • 2019-03-06
      • 2018-11-02
      • 2020-07-31
      • 2020-06-08
      • 1970-01-01
      • 2021-02-11
      • 1970-01-01
      相关资源
      最近更新 更多