Am working on a we开发者_Python百科b application and we allow users to upload files to our server. Am trying to do client side compression before uploading files to the server. What would be the better way to achieve this using HTML5 and JavaScript.
Thanks.
The common mechanism to do what you want is using FileReader and a JavaScript client-side compression library (i.e. compressjs).
In 2022 it's almost too simple, if the browser supports CompressionStream, FormData and Response.
In the example below I use FormData to collect all the fields from the form.
Then I use the readable stream from the file, and pipe it though the compression stream. Then I use Response to read everything from the compressed stream and return it in a blob.
async function compress(file, encoding = 'gzip') {
try {
return {
data: await new Response(file.stream().pipeThrough(new CompressionStream(encoding)), {
headers: {
'Content-Type': file.type
},
}).blob(),
encoding,
};
} catch (error) {
// If error, return the file uncompressed
console.error(error.message);
return {
data: file,
encoding: null
};
}
}
theForm.addEventListener(
'submit',
(event) => event.preventDefault()
)
theForm.addEventListener(
'input',
async function(event) {
// collect all fields
const fd = new FormData(theForm);
// Get 'file handle' from imput elemen
const file = fd.get('theFile');
if (!file) return
const encoding = fd.get('theEncoding');
const compressed = await compress(file, encoding);
theMessage.value = [
'Compressed with', compressed.encoding,
'Source file was', file.size, 'bytes',
'and the compressed file', compressed.data.size,
'saving', ((1 - compressed.data.size / file.size) * 100)
.toFixed(0),
'%.'
].join(' ')
}
)
form>* {
display: block;
width: 100%;
}
<form id="theForm">
<select name="theEncoding">
<option>gzip</option>
<option>deflate</option>
<option>deflate-raw</option>
</select>
<input type="file" name="theFile" id="theFile">
</form>
<output id="theMessage"></output>
加载中,请稍侯......
精彩评论