Ошибка http 422 с DirectUpload / ActiveStorage / Rails - PullRequest
0 голосов
/ 09 апреля 2020

Я пытаюсь добавить некоторые изображения с ajax через DirectUpload / ActiveStorage / Rails 6. Я использую предварительные условия для поддержки ActiveStorage, для использования DirectUpload с Jquery: https://edgeguides.rubyonrails.org/active_storage_overview.html#integrating -with-library- или -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);
    }
  })

На моем хосте это работает для всех файлов. Но когда я пытаюсь опубликовать sh мое приложение в хостере, у меня возникает ошибка для некоторых файлов, всегда одна и та же, после запроса DirectUpload:

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

Я посмотрел запросы XHR в свои webtools в браузере, но полезные данные выглядят одинаково в файле, который работает, и в другом, который не работает:

{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 производит 422 Ошибка InvalidAuthenticityToken

Я заметил, что когда я пытаюсь загрузить файл изображения lo go без использования DirectUpdate во входной файл, файл корректно отправляется на мой сервер.

= f.file_field :logos, direct_upload: true

У вас есть идеи для тестирования?

1 Ответ

0 голосов
/ 17 апреля 2020

Моя проблема шла с IO, который использовался для копирования файла. В ActiveStorage::DiskController#update Rails использует request.body и IO.CopyStream для создания файла, а файл контрольной суммы был создан для проверки созданного файла. А проверка завершается неудачно и выдает ошибку http 422.

Я заметил, что поток ввода-вывода, в режиме dev, был String_IO, тогда как на моем хостере IO был Uswgi_IO. Потому что мой хостер поставляет приложение ruby on rails с Uswgi. Uwsgi_io не содержит методы длины или размера, и когда 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 #:

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

И это работает!

ActionText работает с ActiveStorage для хранения изображений, и у меня была та же проблема с изображениями слишком большого размера. Мой патч позволяет заставить работать ActionText и на моем хостере.

...