Forum

Need some help? Ask our community for its assistance!

You are not logged in.

#1 09-04-2020 11:32:15

oliv
Membre
Registered: 31-05-2013
Posts: 34

[résolu] Erreur Http 422 sur l'upload de fichier en ajax

Salut tout le monde,

J'utilise Rails 6, avec ActiveStorage, et j'envoie mes fichiers en ajax dans le cas d'une liste d'image. J'utilise le script fourni dans la doc d'ActiveStorage :
https://edgeguides.rubyonrails.org/acti … frameworks

Je n'aime pas utiliser cette phrase mais, ça marche sur mon poste, et quand j'ai voulu le déployer sur Alwaysdata, j'avais des erreurs 422, mais bizarrement pas sur tous les fichiers.

J'ai regardé les requêtes XHR dans les webtools, mais je ne vois aucune différence entre un envoi qui fonctionne et un envoi qui ne fonctionne pas :

{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"}

Quand je regarde le log de rails, je vois bien l'erreur retournée par le serveur mais sans pas beaucoup plus d'explications :

 Started POST "/rails/active_storage/direct_uploads" for 2a01:cb05:8b89:7900:6cd9:21e6:8382:f21b at 2020-04-09 08:11:26 +0200
 Processing by ActiveStorage::DirectUploadsController#create as JSON
   Parameters: {"blob"=>{"filename"=>"logo.jpeg", "content_type"=>"image/jpeg", "byte_size"=>17805, "checksum"=>"3GIVi2kNKClfH+9HGYOfkA=="}, "base"=>{"blob"=>{"filename"=>"groupama logo.jpeg", "content_type"=>"image/jpeg", "byte_size"=>17805, "checksum"=>"3GIVi2kNKClfH+9HGYOfkA=="}}}
   ESC[1mESC[35m (1.0ms)ESC[0m  ESC[1mESC[35mBEGINESC[0m
   ESC[1mESC[36mActiveStorage::Blob Create (0.4ms)ESC[0m  ESC[1mESC[32mINSERT INTO `active_storage_blobs` (`key`, `filename`, `content_type`, `byte_size`, `checksum`, `created_at`) VALUES ('3xhp6ftr1pw3vcy1a458b649d2ao', 'logo.jpeg', 'image/jpeg', 17805, '3GIVi2kNKClfH+9HGYOfkA==', '2020-04-09 06:11:26')ESC[0m
   ESC[1mESC[35m (0.3ms)ESC[0m  ESC[1mESC[35mCOMMITESC[0m
 ESC[36m  Disk Storage (0.2ms) ESC[0mESC[34mGenerated URL for file at key: 3xhp6ftr1pw3vcy1a458b649d2ao (https://ateliers-testing.rethink-it.fr/rails/active_storage/disk/eyJfcmFpbHMiOnsizbWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSWhNM2hvY0RabWRISXhjSGN6ZG1ONU1XRTBOVGhpTmpRNVpESmhid1k2QmtWVU9oRmpiMjUwWlc1MFgzUjVjR1ZKSWc5cGJXRm5aUzlxY0dWbkJqc0dWRG9UWTI5dWRHVnVkRjlzWlc1bmRHaHBBbzFGT2cxamFHVmphM04xYlVraUhUTkhTVlpwTW10T1MwTnNaa2dyT1VoSFdVOW1hMEU5UFFZN0JsUT0iLCJleHAiOiIyMDIwLTA0LTA5VDA2OjE2OjI2Ljg2NFoiLCJwdXIiOiJibG9iX3Rva2VuIn19--00b154ebecb531f0e3ba66b81ae2d072c994c9b3)ESC[0m
 Completed 200 OK in 5ms (Views: 0.2ms | ActiveRecord: 1.7ms | Allocations: 2110)
 Started PUT "/rails/active_storage/disk/eyJfcmFpbHMiOnsizbWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSWhNM2hvY0RabWRISXhjSGN6ZG1ONU1XRTBOVGhpTmpRNVpESmhid1k2QmtWVU9oRmpiMjUwWlc1MFgzUjVjRz1ZKSWc5cGJXRm5aUzlxY0dWbkJqc0dWRG9UWTI5dWRHVnVkRjlzWlc1bmRHaHBBbzFGT2cxamFHVmphM04xYlVraUhUTkhTVlpwTW10T1MwTnNaa2dyT1VoSFdVdOW1hMEU5UFFZN0JsUT0iLCJleHAiOiIyMDIwLTA0LTA5VDA2OjE2OjI2Ljg2NFoiLCJwdXIiOiJibG9iX3Rva2VuIn19--00b154ebecb531f0e3ba66b81ae2d072c994c9b3" for 2a01:cb05:8b89:7900:6cd9:21e6:8382:f21b at 2020-04-09 08:11:26 +0200
 Processing by ActiveStorage::DiskController#update as */*
   Parameters: {"encoded_token"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSWhNM2hvY0RabWRISXhjSGN6ZG1ONU1XRTBOVGhpTmpRNVpESmhid1k2QmtWVU9oRmpiMjUwWlc1MFgzUjVjR1ZKSWc5cGJXRm5aUzlxY0dWbkJqc0dWRG9UWTI5dWRHVnVkRjlzWlc1bmRHaHBBbzFGT2cxamFHVmphM04xYlVraUhUTkhTVlpwTW10T1MwTnNaa2dyT1VoSFdVOW1hMEU5UFFZN0JsUT0iLCJleHAiOiIyMDIwLTA0LTA5VDA2OjE2OjI2Ljg2NFoiLCJwdXIiOiJibG9iX3Rva2VuIn19--00b154ebecb531f0e3ba66b81ae2d072c994c9b3"}
 ESC[36m  Disk Storage (0.1ms) ESC[0mESC[31mDeleted file from key: 3xhp6ftr1pw3vcy1a458b649d2aoESC[0m
 ESC[36m  Disk Storage (0.8ms) ESC[0mESC[32mUploaded file to key: 3xhp6ftr1pw3vcy1a458b649d2ao (checksum: 3GIVi2kNKClfH+9HGYOfkA==)ESC[0m
 Completed 422 Unprocessable Entity in 2ms (ActiveRecord: 0.0ms | Allocations: 689)

J'ai essayé avec d'autres types d'images : png, gif, jpg, et parfois ça fonctionne et parfois non, mais c'est bien toujours avec les mêmes fichiers. Ce n'est pas aléatoire, j'arrive à le répéter sur alwaysdata avec un fichier spécifique, alors qu'il fonctionne sur mon poste de dev. Et je n'arrive pas à comprendre quel est la spécificité du fichier pour qu'il ne fonctionne pas sur Alwaysdata.

J'ai essayé ça sans succès, mais en même temps je n'ai pas de Can't verify CSRF token authenticity. dans mon log d'erreur :
https://stackoverflow.com/questions/560 … icitytoken

Dans mon cas, j'utilise le direct upload comme préconisé pour faire de l'ajax, et je remarque que si je ne l'utilise pas, l'envoie de l'image au serveur, via submit du form fonctionne très bien :

= f.file_field :logos, direct_upload: true, \

Donc si vous avez des idées, n'importe laquel, je suis preneur !

Last edited by oliv (16-04-2020 09:52:25)

Offline

#2 10-04-2020 11:17:05

oliv
Membre
Registered: 31-05-2013
Posts: 34

Re: [résolu] Erreur Http 422 sur l'upload de fichier en ajax

Le problème viendrait de la taille des images envoyés en ajax via DirectUpload, dès que la taille fait plus de 18ko ça ne passe plus. (Merci Manuel pour avoir trouvé ça !)
Quand la librairie DirectUpload est utilisé par ActiveText pour stocker des images du contenu dans ActiveStorage, les grosses images ne passent pas non plus via ActiveText.
Ca doit venir d'un paramétrage quelques parts, car j'ai un ami qui fait des sites rails aussi et il n'a pas ce problème sur les autres hébergeurs avec qui il travaille.

Last edited by oliv (10-04-2020 11:37:13)

Offline

#3 15-04-2020 11:17:38

@m4dz
Staff
From: Paris
Registered: 15-01-2018
Posts: 10
Website

Re: [résolu] Erreur Http 422 sur l'upload de fichier en ajax

Bonjour,

si je regarde dans le code d'ActiveStorage sur la méthode d'update qui est appelée lors d'un PUT, il y a deux cas où une 422 peut être levée (https://github.com/rails/rails/blob/mas … rb#L22-L34) :

* Si le fichier ne correspond pas à ses metadonnées (mimetype / content-length)
* Si la méthode d'update échoue

Je vous laisse contrôler que les valeurs du fichiers correspondent bien à ses meta (il s'agit bien d'un jpeg, etc), mais vu que le fichier passe en dev, où je ne pense pas que ce contrôle soit évité, je serai surpris que ça vienne de là.

Donc il reste l'option : la méthode d'update échoue. Est-ce qu'il serait possible d'avoir les logs Rails quand le PUT se passe bien, qu'on puisse identifier d'éventuelles différences ?

Offline

#4 15-04-2020 22:16:38

oliv
Membre
Registered: 31-05-2013
Posts: 34

Re: [résolu] Erreur Http 422 sur l'upload de fichier en ajax

Je l'ai testé avec le code d'Active:Storage justement sur mon projet et c'est l'update qui ne fonctionne pas, le checksum qui est fait à la fin de la copie ne fonctionne pas.
Le stream qui est passé par le request.body correspond à un "uwsgi_IO" et pas à un "string_IO" comme constaté en dev. J'ai l'impression que lors de la copie du stream, il n'arrive pas à trouver la fin du fichier. Il n'y a pas de méthode "length" dans le "uwsgi_IO", alors qu'on en trouve dans le "string_IO".

J'ai remarqué qu'en donnant la variable content_length au body, qui est bonne elle, la copie se fait correctement.

raw_post_body.read(content_length)

J'essaye donc maintenant de mettre à jour la variable RAW_POST_DATA.

request.env['RAW_POST_DATA'] = request.body.read(request.content_length)

Et comme la propriété body est implémenté comme suit, lorsque le code d'Active:Storage va passer, la propriété body sera bonne et à la bonne taille pour être copié.

def body
  if raw_post = get_header("RAW_POST_DATA")
    raw_post = raw_post.dup.force_encoding(Encoding::BINARY)
    StringIO.new(raw_post)
  else
    body_stream
  end
end

Je cherche donc à insérer cette valeur sans toucher au code du framework Active:Storage.

A moins qu'il est une autre solution smile

Offline

#5 16-04-2020 09:51:53

oliv
Membre
Registered: 31-05-2013
Posts: 34

Re: [résolu] Erreur Http 422 sur l'upload de fichier en ajax

C'est bon pour ma part, en ajoutant la variable @RAW_POST_DATA@, la méthode Update du contrôleur ActiveStorage::DiskController.
Et comme ça, on ne touche pas au code d'ActiveStorage.

Pour cela j'ai créé mon contrôleur qui hérite de :

class UploadController < ActiveStorage::DiskController
  def update
    request.env['RAW_POST_DATA'] = request.body.read(request.content_length)    
    super
  end
end

Et ensuite je surcharge la route simplement pour qu'il passe par mon contrôleur :

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

Ce qui me permet d'envoyer des fichiers en ajax via DirectUpload mais aussi de faire fonctionner ActionText qui ne pouvait pas non plus sauvegarder les images importantes, comme il devait utilise ActiveStorage.

Offline

Board footer

Powered by FluxBB