2016-07-15 1 views
0

J'utilise Prototype pour soumettre une demande POST, et le postdata contient un certain nombre de champs, dont l'un est des données binaires d'un fichier (dans ce cas, une feuille de calcul Excel que l'utilisateur a sélectionnée J'utilise l'interface HTML5 FileReader pour obtenir le contenu du fichier via FileReader.readAsBinaryString() qui fonctionne bien. Si j'utilise charCodeAt() pour imprimer divers caractères dans la chaîne, ils sortent avec les valeurs attendues.Soumettre des données binaires via l'appel Prototype Ajax

Cependant, une fois que j'ai mis ces données de chaîne dans un objet (avec les autres champs de formulaire) et que je les ai passées en tant qu'option parameters à Ajax.Request() de Prototype, les données arrivent corrompues. Certaines valeurs de caractères telles que 0x82 sont remplacées par 0xC2 0x82, 0xAC est remplacée par 0xC2 0xAC, et ainsi de suite.

J'ai essayé d'utiliser window.atob() pour encoder la chaîne en base64, mais cela échoue avec InvalidCharacterError: String contains an invalid character, donc il y a clairement un type de traitement que je dois éviter.

Est-ce que quelqu'un sait comment transmettre des données binaires via le Ajax.Request() de Prototype tout en incluant des champs de formulaire supplémentaires dans la même requête?

Répondre

0

Cela nécessite de la magie et de la poussière de lutin. (et pas vraiment)

Premièrement, vous devez placer les valeurs des champs de formulaire comme paramètres d'URL au lieu de POST, puis remplacer le corps du message par le contenu du fichier. Par exemple

new Ajax.Request('/url.php?rawupload=1&id='+$F('id')+'&label='+label, 
    { 
     'method':'post', 
     'postBody':fileobject, 
     'onSuccess':function() { alert('success'); } 
    }); 

fileobject est l'objet de fichier HTML5 récupéré à partir de l'élément d'entrée de téléchargement de fichier

Oui ce ne est pas la solution la plus élégante si vous avez beaucoup de champs de formulaire. Vous pouvez également utiliser Hash#toQueryString si vous avez beaucoup de champs de formulaire pour construire votre chaîne de requête au lieu de les faire à la main

http://api.prototypejs.org/language/Hash/prototype/toQueryString/

1

Pour faire fichier ajax télécharger vous devez vraiment utiliser un objet FormData

var data = new FormData(); 
//var data = new FormData(someForm); if all your fields is in an html form 
// add fields to form 
data.append('fieldname',fieldvalue); 
data.append('filefieldname',fileobject); 
//etc 

new Ajax.Request(url, { 
    contentType: null, 
    method: 'post', 
    postBody: data, 
    onSuccess: successFunction 
}) 

Avec cette méthode, le serveur verra la requête comme s'il était envoyé par un formulaire avec l'attribut enctype="multipart/form-data"

+0

J'ai essayé ceci, en l'envoyant à un script PHP, et j'ai également dû définir 'contentType: 'multipart/form- données » . Cependant, alors il arrive avec l'erreur PHP 'Frontière manquante dans multipart/form-data', donc je suppose que vous ne pouvez pas définir le' postBody' à l'objet 'FormData'? – Malvineous

+0

Ne pas définir contentType à 'multipart/form-data' le définir à null comme indiqué dans ma réponse. – Musa

+1

La définition de 'contentType: null' pour votre réponse (sans guillemets ni rien) entraîne l'envoi de la requête HTTP par le navigateur avec' Content-Type: null; jeu de caractères = UTF-8'. Il semble que la limite MIME doive être spécifiée dans l'en-tête HTTP Content-Type pour que les données 'multipart/form-type' fonctionnent correctement, mais je ne vois pas comment cela devrait être fait. – Malvineous