цель состоит в том, чтобы сделать 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Характеристики:
Если потребуется дополнительная информация, просто дайте мне знать в комментариях. Я очень хочу это предоставить. Спасибо.
строка, содержащая данные, закодированные на двоичном уровне (описывается здесь: developers.google.com/protocol-buffers/docs/encoding); «данные повреждены» означает, что «сериализация данных отличается от того, что в итоге оказывается в массиве байтов в Angular» -> Я расширю свой вопрос.
Но вы просто повторяете строку из PHP. Вы не пытаетесь закодировать его в каком-либо двоичном формате. Это твой вопрос? Если так, то это слишком широко. Покажи нам, что ты пробовал и как не получилось.
Как я уже писал, я пробовал, например, header('Content-Type:binary/octet-stream;');, который в сочетании с echo должен возвращать строку / данные как есть. Судя по ответу на stackoverflow.com/questions/11022213/php-write-binary-respon se, строки и байтовые массивы в любом случае одинаковы. В конце шестнадцатеричный анализ показал несколько дополнительных / измененных / удаленных байтов.
Все, что нужно сделать, это изменить значение заголовка HTTP. Это не меняет, какие данные отправляются.
полезно знать - я не знал об этом. Я добавил еще один пример, который должен сделать проблему более очевидной. (Я также редактировал предыдущий комментарий)
Если я не понимаю все это неправильно, проблема в том, что вы хотите отправлять данные из PHP в проприетарном двоичном формате, и вы не пытаетесь это сделать. Если вы хотите, чтобы он выглядел так, как описано в этой ссылке Google, вам нужно написать код PHP для этого.
Функция serializeToString() уже выполняет преобразование в формат, описанный в ссылке Google (сериализация JFYI json также возможна с serializeJsonToString()). В противном случае он точно не работал бы с base64.






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