JavaScript:为什么 `FileReader.readAsBinaryString()` 会破坏结果
JavaScript: Why `FileReader.readAsBinaryString()` corrupts result
我有一个文件输入。在 change
事件中,我将指定文件读取到 post JSON 对象中的数据到 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 ] );
}
在我的测试中,我尝试阅读 composer.phar
。它指出 MD5 校验和不是真正的校验和。所以很明显 FileReader 没有正确读取文件。任何假设会发生什么?也许 FileReader 使用了一些编码?
阐明我的需求
当我将数据发送到 REST API 时,multipart/form-data
没有请求。因此我不能使用 PHP 的 $_FILES
服务器端。
我需要在请求正文中的内容类型为 application/json
的 JSON 对象中发送文件。因此我需要在客户端手动读取文件并将其存储在服务器端。目前无法保证客户端数据,因为读取数据的 MD5 校验和与所选二进制文件的真实 MD5 校验和不匹配。
示例请求正文
{
"id": "d0f11715-c0b1-4a1d-b471-4408c78fbe01",
"data": "This is some JSON encoded string of possibly binary file data."
}
更新
我声明读取的数据长度与原始文件大小完全一致
更新
此问题已被标记为重复,但上述回答并未解决我的问题。我尝试了提到的两个例子。
bashcmdmd5sum
计算出的MD5校验和
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
我更改了@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 ] );
}
所以虽然现在很明显读取的数据是正确的,但我只需要处理读取的数据。 Base64解码值服务器端的校验和现在也正确,建议使用FileReader.readAsArrayBuffer()
。
我有一个文件输入。在 change
事件中,我将指定文件读取到 post JSON 对象中的数据到 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 ] );
}
在我的测试中,我尝试阅读 composer.phar
。它指出 MD5 校验和不是真正的校验和。所以很明显 FileReader 没有正确读取文件。任何假设会发生什么?也许 FileReader 使用了一些编码?
阐明我的需求
当我将数据发送到 REST API 时,multipart/form-data
没有请求。因此我不能使用 PHP 的 $_FILES
服务器端。
我需要在请求正文中的内容类型为 application/json
的 JSON 对象中发送文件。因此我需要在客户端手动读取文件并将其存储在服务器端。目前无法保证客户端数据,因为读取数据的 MD5 校验和与所选二进制文件的真实 MD5 校验和不匹配。
示例请求正文
{
"id": "d0f11715-c0b1-4a1d-b471-4408c78fbe01",
"data": "This is some JSON encoded string of possibly binary file data."
}
更新
我声明读取的数据长度与原始文件大小完全一致
更新
此问题已被标记为重复,但上述回答并未解决我的问题。我尝试了提到的两个例子。
bashcmdmd5sum
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
我更改了@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 ] );
}
所以虽然现在很明显读取的数据是正确的,但我只需要处理读取的数据。 Base64解码值服务器端的校验和现在也正确,建议使用FileReader.readAsArrayBuffer()
。