带有DirectUpload / ActiveStorage / Rails的错误http 422

问题描述 投票:0回答:1

我尝试通过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

您有什么想法要测试吗?

rails-activestorage ruby-on-rails-6
1个回答
0
投票

我的问题来自用于复制文件的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的新控制器,以便在RAW_POST_DATA动作之前分配Disk#update

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。

© www.soinside.com 2019 - 2024. All rights reserved.