Да, передача USVString в конструктор Blob автоматически преобразует его в UTF-8 .
Параметр type
используется только в качестве средства извлечения ресурсов в качестве Content-Type, соответствующего переданным данным. Заголовок charset
содержит только подсказку о том, что такое кодировка контента, однако он не меняет контент вообще.
Одним из методов, который будет использовать эту информацию charset
, является FileReader.readAsText()
(если параметр encoding
не задан).
const data = "é";
const blob1 = new Blob([data], {type: 'plain/text;charset=windows-1252'});
const blob2 = new Blob([data], {type: 'plain/text;'});
readAsText(blob1).then(res => console.log('read as CP-1252:', res));
readAsText(blob2).then(res => console.log('read as UTF-8:', res));
readAsArrayBuffer(blob1).then(res => console.log("actual bytes content CP-1252:", ...new Uint8Array(res)));
readAsArrayBuffer(blob2).then(res => console.log("actual bytes content UTF-8:", ...new Uint8Array(res)));
function readAsText(blob) {
return new Promise(res => {
const reader = new FileReader();
reader.onload = e => res(reader.result);
reader.readAsText(blob);
});
}
function readAsArrayBuffer(blob) {
return new Promise(res => {
const reader = new FileReader();
reader.onload = e => res(reader.result);
reader.readAsArrayBuffer(blob);
});
}
.as-console-wrapper {
max-height: none!important;
}
Как видите, оба BLOB-объекта на самом деле содержат одни и те же байтовые данные: один из символов UTF-8 é
.
Так что для того, что вы хотите, вам нужно сгенерировать ваши BLOB-объекты из TypedArray, который содержит ваши данные, уже закодированные как CP-1252.
Раньше была возможность использовать API TextEncoder для кодирования из USVStrings в произвольные кодировки, но это было удалено из спецификаций и браузеров.
Вам нужно будет использовать библиотеку, чтобы выполнить преобразование. Здесь я буду использовать этот :
const data = new TextEncoder('windows-1252', {
NONSTANDARD_allowLegacyEncoding: true
}).encode("é"); // now `data` is an Uint8Array
const blob1 = new Blob([data], {type: 'plain/text;charset=windows-1252'});
const blob2 = new Blob([data], {type: 'plain/text;'});
readAsText(blob1).then(res => console.log('read as CP-1252:', res));
readAsText(blob2).then(res => console.log('read as UTF-8:', res));
readAsArrayBuffer(blob1).then(res => console.log("actual bytes content CP-1252:", ...new Uint8Array(res)));
readAsArrayBuffer(blob2).then(res => console.log("actual bytes content UTF-8:", ...new Uint8Array(res)));
function readAsText(blob) {
return new Promise(res => {
const reader = new FileReader();
reader.onload = e => res(reader.result);
reader.readAsText(blob);
});
}
function readAsArrayBuffer(blob) {
return new Promise(res => {
const reader = new FileReader();
reader.onload = e => res(reader.result);
reader.readAsArrayBuffer(blob);
});
}
.as-console-wrapper {
max-height: none!important;
}
<script>
// force installation of the polyfill...
window.TextEncoder = null;
</script>
<script src="https://cdn.jsdelivr.net/gh/inexorabletash/text-encoding/lib/encoding-indexes.js"></script>
<script src="https://cdn.jsdelivr.net/gh/inexorabletash/text-encoding/lib/encoding.js"></script>