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.