I have a file input. On the change
event I read the specified file to post the data within a JSON object to an API.
function changeHandler( event ) {
const fileReader = new FileReader();
fileReader.addEventListener(
'loadend',
function ( event )
{
console.log( CryptoJS.MD5( event.originalTarget.result ).toString() );
/** ... */
}
);
fileReader.readAsBinaryString( event.originalTarget.files[ 0 ] );
}
In my testing I tried to read the composer.phar
. It states out the MD5 checksum isn't the real checksum. So it's clear the FileReader doesn't read the file correctly. Any assumptions what happpens? Maybe the FileReader uses some encoding?
While I send the data to a REST API there's no request with multipart/form-data
. Thus I cannot use PHP's $_FILES
server side.
I need to send the file within a JSON object with content type application/json
within the request body. Thus I need to read the file manually client side and to store it server side. And currently the client side data isn't guaranteed while the MD5 checksum of the read data doesn't match the real MD5 checksum of the binary file selected.
A sample request body
{
"id": "d0f11715-c0b1-4a1d-b471-4408c78fbe01",
"data": "This is some JSON encoded string of possibly binary file data."
}
I states out the length of the data read is exactly the same as the original file size.
This question has been flagged a duplicate but the mentioned answere didn't resolve my issue. I tried both examples mentioned.
https://stackoverflow.com/a/34493461/2323764
The MD5 checksum calculated by bash cmd md5sum
56f13c034e5e0c58de35b77cbd0f1b0b resources/composer.phar
function changeHandler( event ) {
const fileReader = new FileReader();
fileReader.addEventListener(
'loadend',
function ( event )
{
console.log( CryptoJS.MD5( event.target.result ).toString() );
}
);
fileReader.readAsBinaryString( event.target.files[ 0 ] );
}
// outputs 784102b153672149418605c1d4abcc3c
function changeHandler( event ) {
const fileReader = new FileReader();
fileReader.addEventListener(
'loadend',
function ( event )
{
const wordArray = CryptoJS.lib.WordArray.create( event.target.result );
console.log( CryptoJS.MD5( wordArray ).toString() );
}
);
fileReader.readAsArrayBuffer( event.target.files[ 0 ] );
}
// outputs 231bc133db6bdf3f665b53b0d2f631d1
I changed the used library as mentioned by @kaiido.
https://github.com/satazor/js-spark-md5
function changeHandler( event )
{
const fileReader = new FileReader();
fileReader.addEventListener(
'loadend',
function ( event )
{
const arrayBuffer = new SparkMD5.ArrayBuffer();
arrayBuffer.append( event.target.result );
console.log( arrayBuffer.end() );
base64Encoded = btoa(
[].reduce.call(
new Uint8Array( event.target.result ),
function ( p, c )
{
return p + String.fromCharCode( c )
},
''
)
);
}
);
fileReader.readAsArrayBuffer( event.target.files[ 0 ] );
}
So while now it's clear the read data is correct I just have to process the data read. The checksum of the Base64 decoded value server side is also correct now while the usage of FileReader.readAsArrayBuffer()
is recommended.