Двоичные данные из PHP в Angular 6 через http

цель состоит в том, чтобы сделать http-запрос (пустой) из Angular 7 в PHP для получения двоичных данных в Angular для использования с protobuf3. Более конкретно, двоичные данные (закодированные, как описано здесь: https://developers.google.com/protocol-buffers/docs/encoding) в PHP (исходный код) инкапсулируются в строку, а целью в Angular является Uint8Array.

Поэтому в настоящее время у меня есть следующий рабочий код:

Код PHP (простой корневой шаблон ProcessWire):

header('Content-Type: application/b64-protobuf');
…
echo base64_encode($response->serializeToString());

Угловой:

let res = this.httpClient.get(`${this.API_URL}`, { responseType: 'text' });
  res.subscribe((data) => {

  let binary_string = atob(data);
  let len = binary_string.length;
  let bytes = new Uint8Array(len);
  for (let i = 0; i < len; i++) {
    bytes[i] = binary_string.charCodeAt(i);
  }

  let parsedResponse = pb.Response.deserializeBinary(bytes)      
})

Как видите, я кодирую данные как base64 перед их отправкой. Таким образом, это не так эффективно, как могло бы быть, потому что base64 уменьшает количество информации на символ. Я уже довольно много пытался заставить работать двоичную передачу, но в конце концов данные всегда искажаются, т.е. переменная bytes не идентична аргументу base64_encode. Но все же, согласно некоторым источникам (например, PHP написать двоичный ответ, Двоичные данные повреждены с php на AS3 через http (никто не говорит, что это будет невозможно)), это должно быть возможно.

Итак, мой вопрос: что нужно изменить для прямой передачи двоичных данных? Это вообще возможно?

Что я пробовал?

  • используя разные заголовки, такие как header('Content-Type:binary/octet-stream;'); или используя Blob в Angular.
  • Я также пытался удалить base64_encode из кода PHP и atob из кода Angular. Результат: содержимое данных изменяется между serializeToString и deserializeBinary(bytes), что нежелательно.
  • Я проверял возможные символы до <?php

Характеристики:

  • PHP 7.2.11
  • Apache 2.4.35
  • Угловой 7.0.2

Если потребуется дополнительная информация, просто дайте мне знать в комментариях. Я очень хочу это предоставить. Спасибо.

"данные всегда портятся" что это значит? Кроме того, я бы предположил, что результатом $response->serializeToString() будет строка, а не «двоичные данные».

miken32 27.12.2018 23:13

строка, содержащая данные, закодированные на двоичном уровне (описывается здесь: developers.google.com/protocol-buffers/docs/encoding); «данные повреждены» означает, что «сериализация данных отличается от того, что в итоге оказывается в массиве байтов в Angular» -> Я расширю свой вопрос.

JFFIGK 27.12.2018 23:17

Но вы просто повторяете строку из PHP. Вы не пытаетесь закодировать его в каком-либо двоичном формате. Это твой вопрос? Если так, то это слишком широко. Покажи нам, что ты пробовал и как не получилось.

miken32 27.12.2018 23:20

Как я уже писал, я пробовал, например, header('Content-Type:binary/octet-stream;');, который в сочетании с echo должен возвращать строку / данные как есть. Судя по ответу на stackoverflow.com/questions/11022213/php-write-binary-respon‌ se, строки и байтовые массивы в любом случае одинаковы. В конце шестнадцатеричный анализ показал несколько дополнительных / измененных / удаленных байтов.

JFFIGK 27.12.2018 23:24

Все, что нужно сделать, это изменить значение заголовка HTTP. Это не меняет, какие данные отправляются.

miken32 27.12.2018 23:25

полезно знать - я не знал об этом. Я добавил еще один пример, который должен сделать проблему более очевидной. (Я также редактировал предыдущий комментарий)

JFFIGK 27.12.2018 23:41

Если я не понимаю все это неправильно, проблема в том, что вы хотите отправлять данные из PHP в проприетарном двоичном формате, и вы не пытаетесь это сделать. Если вы хотите, чтобы он выглядел так, как описано в этой ссылке Google, вам нужно написать код PHP для этого.

miken32 27.12.2018 23:45

Функция serializeToString() уже выполняет преобразование в формат, описанный в ссылке Google (сериализация JFYI json также возможна с serializeJsonToString()). В противном случае он точно не работал бы с base64.

JFFIGK 27.12.2018 23:47
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
8
317
0

Другие вопросы по теме