Я использую Vue.js во внешнем интерфейсе. У меня есть Node.js, Express, PostgreSQL (с Sequelize ) на сервере.
Я храню элемент в базе данных, который содержит эскиз изображения.
Модель базы данных
const Item = sequelize.define('item', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: Sequelize.TEXT,
allowNull: false,
},
image: {
type: Sequelize.BLOB('long'),
allowNull: true,
},
С точки зрения базы данных, изображение хранится как BLOB-объект, и я думаю, что это нормально (и да, я знаю, что не рекомендуется размещать изображения в базе данных).
Я наблюдаю в браузере, что объект, к которому я обращаюсь в моем шаблоне Vue с помощью this.item.image
, является объектом типа Buffer
.
Добавление в базу данных
Я добавляю элемент в базу данных в браузере с этим в моем шаблоне vue:
<label for="image" class="itemCreate__field itemCreate__field--image">
<span class="itemCreate__fieldLabel">Image</span>
<input id="file" type="file" accept="image/*" @change="onFileChange"/>
<img v-if="itemPreviewImage" :src="itemPreviewImage" />
</label>
И этот HTML опирается на эти методы:
onFileChange(evt) {
const files = evt.target.files || evt.dataTransfer.files;
if (!files.length) return;
this.createImage(files[0]);
},
createImage(file) {
const image = new Image();
const reader = new FileReader();
reader.onload = evt => {
this.itemPreviewImage = evt.target.result;
this.item.image = evt.target.result;
}
reader.readAsDataURL(file);
},
У меня есть это в шаблоне vue, который отображает изображение:
<div v-if="item.image">
<img :src="imgUrl" alt="Picture of item"/>
</div>
Рендеринг из базы данных
Я пробовал следующие подходы, которые не работают:
createObjectUrl
заимствовано из здесь :
imgUrl(){
const objUrl = window.URL.createObjectURL(new Blob(this.item.image.data));
return objUrl;
}
Создание строки base64, заимствованной из здесь :
imgUrl(){
const intArray = new Uint8Array(this.item.image.data);
const reducedArray = intArray.reduce((data, byte) => data + String.fromCharCode(byte), '');
const base64String = `data:image/png;base64, ${btoa(reducedArray)}`;
return base64String;
}
Создание нового Uint8Array
с последующим получением objectUrl (заимствовано здесь ):
imgUrl(){
const arrayBuffer = new Uint8Array(this.item.image);
const blob = new Blob([arrayBuffer], {type: "image/png"});
return window.URL.createObjectURL(blob);
}
Во всех случаях (включая некоторые попытки с FileReader) я получаю испорченные изображения. Я не получаю ошибки в консоли, хотя.
Я думаю проблема в том, что я не отправляю правильные данные в базу данных.
Я отправляю Ajax-запрос с прикрепленным файлом в качестве свойства, и мне, вероятно, следует преобразовать его в ¿что-то еще?