Невозможно установить правильный тип MIME при нарезке BLOB-объектов - PullRequest
0 голосов
/ 02 января 2019

Я обнаружил ошибку, из-за которой изображения svg не могли отображаться в Safari. После расследования я понял, что это связано с тем, что я загружаю ресурсы как пакеты / архивы файлов, которые я разделяю в браузере.

Когда я загружаю ресурсы, я получаю текстовый шарик. Я использую blob.slice () для извлечения ресурса, передавая правильный тип MIME. Тем не менее, кажется, что новый BLOB-объект не имеет правильный тип MIME, но все еще старый (простой текст). В Chrome и Firefox оказывается, что изображение может отображаться, даже если его тип MIME неверен, но не в Safari.

Вот код, который не работает:

const blob = new Blob([ressource], {
  type: "text/plain",
});

const slicedBlob = blob.slice(0, blob.size, "image/svg+xml"); 
// slicedBlob.type is "text/plain"

Я также воспроизвел несколько минимальных тестовых случаев: https://jsbin.com/yavaxadalo/edit?js,output

Из документов MDN и спецификаций W3C похоже, что я использую метод так, как он предназначен, но, может быть, я что-то упустил?

1 Ответ

0 голосов
/ 04 января 2019

Я должен признать, что немного не в курсе об ошибке этого Safari.Вероятно, это должно быть , о котором сообщалось .

Я хотел бы отметить, что ваш jsbin немного вводил в заблуждение, поскольку BLOB-объект, возвращаемый методом слайса, правильно установил для type значение 'image/svg+xml' (вы регистрировали тип оригинала blob2), но это только делает вещи еще более странными ...

Теперь я не слишком понимаю, почему вы хотите использовать Blob.sliceздесь, если вы просто хотите изменить тип этого BLOB-объекта, вы можете просто создать новый, используя конструктор Blob(), который также принимает другие BLOB-объекты как blobType .

const blob1 = new Blob([
`<svg xmlns="http://www.w3.org/2000/svg">
  <rect width="100" height="100"/>
</svg>`
], {type: 'text/plain'});
console.log(blob1.type);

const blob2 = new Blob([blob1], {type: 'image/svg+xml'});
console.log(blob2.type);
img.src = URL.createObjectURL(blob2);
<img id="img">

И если вы действительно хотите использовать метод Blob.slice, то в качестве обходного пути вы можете создать новый из конструктора Blob, который обернет егоправильно:

const blob1 = new Blob([
`<svg xmlns="http://www.w3.org/2000/svg">
  <rect width="100" height="100"/>
</svg>[BAD-DATA]`
], {type: 'text/plain'});

// if we need to slice it
const sliced = blob1.slice(0, blob1.size - '[BAD-DATA]'.length);
// wrap it again for Safari...
const blob2 = new Blob([sliced], {type: 'image/svg+xml'});
img.src = URL.createObjectURL(blob2);
<img id="img">
...