Как получить массив байтов внутри JSON

Я пытаюсь получить PDF-файл с сервера, который будет заключен в JSON.

Если я отправляю только массив байтов PDF-файла на внешний интерфейс, я могу правильно его прочитать, установив responseType в arraybuffer, тогда я могу загрузить PDF-файл:

var blob = new Blob([data], { type: application/pdf});
    if ($window.navigator && $window.navigator.msSaveOrOpenBlob) {
        $window.navigator.msSaveOrOpenBlob(blob);
    } else {
        var a = document.createElement("a");
        document.body.appendChild(a);
        var fileURL = URL.createObjectURL(blob);
        a.href = fileURL;
        a.download = fileName;
        a.click();
    }
}

Однако, когда сервер пытается отправить JSON с массивом байтов внутри, если я установлю responseType на JSON, я не смогу преобразовать большой двоичный объект. Но если я установлю responseType в arrayBuffer, я получу массив arrayBuffer, как мне преобразовать его в JSON, сохранив при этом возможность извлечения PDF-файла после этого:

JSON, который я получаю, имеет вид:

{
  result: true,
  value: <the pdf byte array>,
  errorMessage: null
}

person user1294510    schedule 29.01.2019    source источник
comment
JSON не предназначен для двоичного содержимого. Вы должны использовать строковый формат, поэтому вам нужно кодировать двоичный файл в строковый формат, а затем декодировать его, чтобы вернуть его в двоичный формат. Я настоятельно рекомендую вам использовать base64, как ответил Петр Аверьянов.   -  person Pierre Emmanuel Lallemant    schedule 12.02.2019


Ответы (3)


Вы должны преобразовать байты в строку base64 и в пользовательском интерфейсе прочитать из нее байты.

person Petr Averyanov    schedule 07.02.2019

Если предполагается, что приведенная ниже переменная представляет структуру responseText:

responseText = {
      result: true,
      value: <the pdf byte array>,
      errorMessage: null
}

responseText.value - массив байтов. Если массив байтов уже набран как Uint8Array, то это сработает.

(Примечание. Существуют и другие типизированные массивы, поэтому выберите какой из них лучше всего подходит для вашего случая):

var blob = new Blob([response.value], { type: 'application/pdf'});
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(blob);
} else {
    var a = document.createElement("a");
    document.body.appendChild(a);
    var fileURL = URL.createObjectURL(blob);
    a.href = fileURL;
    a.download = 'test';//filename
    a.click();
}

Однако, если есть массив строк или целочисленный массив байтов, как показано ниже:

responseText.value = [145, 229, 216, 110, 3]

и его нужно преобразовать в типизированный массив байтов, тогда будет работать следующее:

var ba = new Uint8Array(responseText.value);

или

var ba = new Uint8Array([145, 229, 216, 110, 3]);

Следовательно,

var blob = new Blob([ba], { type: 'application/pdf'}); 

Таким образом, массив байтов можно использовать для создания большого двоичного объекта, поэтому файл загружается при возникновении события click.

person Nik B    schedule 10.02.2019
comment
Не то чтобы этот ответ сам по себе говорил что-то неправильное, но надеюсь, никто этого не делает. Если мы возьмем точный пример в этом ответе, то двоичные данные на самом деле составляют всего 5 байтов. Представив его как массив Uint8, преобразованный в строку, закодированную как UTF-8, мы теперь имеем 23 байта полезной нагрузки (примерно на 336% больше). Эквивалент base64 (keXYbgM=) даже с необязательным дополнением составляет всего 8 байтов (примерно на 36 % больше исходного). - person Kaiido; 27.05.2019

Установите значение массива байтов как строку. При разборе JSON преобразуйте строку в массив байтов.

ссылайтесь на этот Java Byte Array to String to Byte Array для пример.

person Elie Nassif    schedule 05.02.2019