Как base64 кодировать двоичное изображение в JS для просмотра в браузере - PullRequest
0 голосов
/ 06 ноября 2019

У нас есть проблема с отображением в браузере (на самом деле Chrome) двоичных изображений, получаемых из REST backend API. Конечная точка REST бэкэнда, определенная в Java следующим образом

@GetMapping(path = "/images/{imageId:\\d+}/data", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public @ResponseBody byte[] getImageData(@PathVariable long imageId) {
    return ... skipped ...
}

На внешнем интерфейсе мы делаем следующие шаги:

  1. запрашиваем данные изображения через fetch вызов метода JS
    async function getImage(id) {
        return await fetch(`${URL}/images/${id}/data`, {
            method: 'GET',
            headers: new Headers(HEADERS)
        }).then(response => {
             return response.text();
        });
    }
Таким образом, во внешнем интерфейсе у нас есть необработанные двоичные данные изображения в этом формате (пока все хорошо - это действительно двоичные данные JPEG). Прилагается источник JPEG

https://www.dropbox.com/s/8mh6xz881by5lu1/0gCrmsLkgik.jpg?dl=0

затем мы вызываем этот код для получения изображения в кодировке base64
    let reader = new FileReader();
        reader.addEventListener('loadend', event => {
        console.log(event.srcElement.result)
    });

    reader.readAsDataURL(new Blob([data]));
в результате мы имеем что-то выглядит как закодированные в base64 данные

https://www.dropbox.com/s/uvx042j2dgizkr9/base64.txt?dl=0

мы пытались поместить данные, закодированные в base64, в элемент <img>, но безуспешно: (

Итак, вопрос в том, , как получить на фронтэнде правильные изображения base64 для просмотра в браузере? Что мы делаем не так?

1 Ответ

1 голос
/ 06 ноября 2019

Вот некоторый рабочий код, основанный на этом примере и комментарии @ что-то здесь выше. Обратите внимание на то, как обрабатывается response в getImage:

function getImage(id) {
    return fetch(`https://placekitten.com/200/140`, {
        method: 'GET',
    }).then(response => {
        return response.blob(); // <- important
    });
}

async function loadAndDisplay() {
    let blob = await getImage();
    let imageUrl = URL.createObjectURL(blob);
    let img = document.createElement('img');
    img.src = imageUrl;
    document.body.appendChild(img)
}

loadAndDisplay()

Тем не менее, гораздо более простым вариантом было бы просто вставить тег типа <img src=/images/id/data> и оставить всю загрузку / отображение в браузере. В этом случае ваш бэкэнд должен предоставить правильный тип контента.

...