简体   繁体   中英

Submit binary data via Prototype Ajax call

I'm using Prototype to submit a POST request, and the postdata contains a number of fields, one of which is binary data from a file (in this case an Excel spreadsheet the user has selected for upload.)

I am using the HTML5 FileReader interface to get the contents of the file via FileReader.readAsBinaryString() which works well. If I use charCodeAt() to print various characters in the string then they come out with the expected values.

However once I put this string data in an object (along with the other form fields) and pass it as the parameters option to Prototype's Ajax.Request() , the data arrives corrupted. Certain character values like 0x82 are replaced with 0xC2 0x82 , 0xAC is replaced with 0xC2 0xAC , and so on.

I tried using window.atob() to base64 encode the string, but this fails with InvalidCharacterError: String contains an invalid character , so clearly there is some kind of processing going on which I need to avoid.

Does anyone know how to pass binary data through Prototype's Ajax.Request() while also including additional form fields in the same request?

To do ajax file upload you should really use a FormData object

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
})

With this method the server will see the request like if it was sent by a form with attribute enctype="multipart/form-data"

Doing this requires magic and pixie dust. (well not really)

firstly you would need to put the form fields values as URL parameters instead of POST and then override the post body with the file contents. For example

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

fileobject is the HTML5 file object retrieved from the file upload input element

Yes its not the most elegant solution if you have lots of form fields. You can also use Hash#toQueryString if you do have lots of form fields to build your query string instead of doing them by hand

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM