Передача данных MessagePack
Пытаюсь передавать с бэка Python Django данные в формате MessagePack. Из модели я получаю данные, которые пытаюсь упаковать в MessagePack, однако если попытаться упаковывать сразу объекты(при получении из модели, они поставляются в формате QuerySet), то стандартный msgpack.packb - не сработает, т.к. не умеет с этим типом взаимодействовать. Поэтому я использую библиотеку nameko-django(возможно, кто-то еще знает возможные решения, но суть не в этом). Получаем в представлении(views.py) такую функцию:
qs = list(Post.objects.filter(published=True))
data = dumps(qs)
return HttpResponse(data)
Благодаря "list(Post.objects...)" серелизуется не только название объекта, но и все возможные поля(как раз то, что и нужно). В итоге получаем данные, как на скриншоте(неизвестные символы отображаются из-за того, что браузер не понимает двоичного формата).
Чтобы получить данные со страницы API и отобразить у клиента используется VANILA JS:
function loadContentPost() {
const http = new XMLHttpRequest();
http.onreadystatechange = function () {
// Проверим, пришел ли запрос - 200 запрос прошел. === - проверка и по значению и по типу. Они должны быть равны
if (this.readyState === 4 && this.status === 200) {
// Получаем данные из запроса
console.log(this.responseText)
** //преобразование в байты для MessagePack
var bytes = []; // char codes
for (var i = 0; i < this.responseText.length; ++i) {
var code = this.responseText.charCodeAt(i);
bytes = bytes.concat([code]);
}
// for (var i = 0; i < input.length; i++) {
// output.value += input[i].charCodeAt(0).toString(2) + " ";
// }
const content = msgpack.deserialize(bytes);
console.log(bytes)
**
let html = "";
console.log(content)
for (let i = 0; i < content.length; i++) {
const fields = content[i].fields;
let date = new Date(fields.time_create_post.slice(0, fields.time_create_post.indexOf('.')));
date = `${date.getDate()}.${date.getMonth()+1 > 10 ? date.getMonth()+1 : '0'.concat(date.getMonth()+1)}.${date.getFullYear()} ${date.getHours()}:${date.getMinutes()}`;
html += `<a href="./post/${content[i].pk}-${fields.slug}">
<li>
<div class="post">
<div class="img__post">\n`;
if (fields.image !== "") {
html += `<img class="image__post" src="/media/${fields.image}">\n`;
}
html += `</div>
<div class="text__post">
<div class="content__post">
<h1 class="headPostTitle">${fields.title}</h1>
<p class="dataPost">${date}</p>
<p class="headPostContent">${fields.content.replace(/(?:\\[rn])+/g, "").split(' ').filter( str => str != '').slice(0, 65).join(' ')} ...</p>
</div>
</div>
</div>
</li>
</a>`;
}
document.getElementById('content').innerHTML = html;
}
};
http.open("GET", `./api/msgpack/` , true); // тут исправить на
nextItem += count;
http.send();
}
loadContentPost();
Следующими строками из вышеуказанного кода, я получаю закодированный текст, со страницы API, после чего преобразовываю его в байты(числа), для того, чтобы ДЕсерелизатор понимал что это MessagePack:
var bytes = []; // char codes
for (var i = 0; i < this.responseText.length; ++i) {
var code = this.responseText.charCodeAt(i);
bytes = bytes.concat([code]);
}
// for (var i = 0; i < input.length; i++) {
// output.value += input[i].charCodeAt(0).toString(2) + " ";
// }
const content = msgpack.deserialize(bytes);
console.log(bytes)
let html = "";
console.log(content)
Единственный (де)серелизатор на MessagePack для JS сайтов я нашел от ygoe. Однако, после десерелизациия, получаю значение "-3", а не текст, который мне нужен.
Как возможно, распаковать на фронте данные зашифрованные в MessagePack?
p.s. во views.py можно еще сделать передачу через msgpack.packb, однако для это нужно изначально серелизовать в JSON и только потом в messagepack, я понимаю, что это не правильно, но как вариант - имеет право на существование. Однако та же проблема , с получение данных на фронте.