#html #node.js #reactjs #mongodb
#HTML #node.js #reactjs #mongodb
Вопрос:
Я пытаюсь отобразить изображение, полученное из mongodb, но я продолжаю получать ERR_INVALID_URL:http://prntscr.com/tzyqtd
В mongodb оно определяется как:
coverImage: {
type: Buffer,
},
В node я считываю изображение с помощью fs:
const img = fs.readFileSync(
path.resolve(__dirname, "../../images/img/grippers/gripper1.png"),
{ encoding: "base64" }
);
Затем я сохраняю его в mongodb, просто вводя это img
в coverImage
поле.
На моей интерфейсной стороне, когда я делаю запрос, я получаю объект с изображением в нем:
const retrievedConfig = await axios.get(
`http://localhost:3000/config/one/ROBOT_1`
);
console.log(retrievedConfig.data.Configs[0].Pallet.coverImage);
Таким образом, это выводит изображение, и изображение содержит два поля, {type: Buffer, data: Array[3750]}
Затем, когда я пытаюсь его отобразить:
<img src={`data:image/png;charset=utf-8;base64,${img.data.toString("base64")}`}/>
Это выдает мне ERR_INVALID_URL
ошибку.
Теперь, одна вещь, которую я заметил, это то, что даже с toString("base64")
я не думаю, что он действительно преобразуется в base64 по какой-то причине, потому что он все еще в 8-битных числах (от 0 до 255). http://prntscr.com/tzysh5
Но когда я читаю его с помощью fs на серверной части, оно находится в base64 http://prntscr.com/tzysrz (это сразу после fs.read и перед сохранением в базе данных)
EDIT:
Я попытался использовать btoa
функцию во внешнем интерфейсе, и она действительно преобразовала ее в base64 (однако я понятия не имею, почему другой способ не сработал, у меня точно такой же код в другом приложении, работающем без btoa и отображаемых изображений), но даже после преобразования оно все еще не отображало изображение (просто показывало сломанное изображение http://prntscr.com/tzyw1m ), но ошибок нет.
Ответ №1:
Недавно я столкнулся с аналогичной проблемой — у меня получилось вручную преобразовать данные из Uint8Array
в base64:
function convertBufferToBase64(buffer) {
let binaryStr = '';
const byteArray = new Uint8Array(buffer);
for (let i = 0; i < byteArray.byteLength; i ) {
binaryStr = String.fromCharCode(bytes[i]);
}
return btoa(binary);
}
Используйте его следующим образом:
<img src={`data:image/png;charset=utf-8;base64,${convertBufferToBase64(img.data)}`}/>
Редактировать:
Поскольку вы уже читаете изображение, используя { encoding: "base64" }
опцию, не должно быть необходимости конвертировать между буферами. Изменение типа данных mongoose из coverImage
на String
и использование его значения во внешнем интерфейсе должно устранить проблему.
Комментарии:
1. Спасибо, но это тоже не помогает, оно по-прежнему показывает его как поврежденное изображение
2. На всякий случай — можете ли вы убедиться, что строка base64 является допустимым изображением? Вы можете попробовать это здесь, например: codebeautify.org/base64-to-image-converter
3. хорошо, я пробовал с изображением после его создания на стороне сервера, это изображение отображается просто отлично, но другое, когда оно преобразуется обратно на стороне react, не является допустимым изображением, и строка отличается
4. Подождите секунду — вы читаете файл, используя
{ encoding: "base64" }
значение, котороеimg
фактически уже будет строкой в кодировке base64. Не должно быть необходимости конвертировать из / в буферы. Можете ли вы попробовать изменить тип coverImage наString
?5. это сработало! Я изменил на string и удалил все преобразования на стороне интерфейса, и это сработало. Спасибо. Отредактируйте свой ответ, чтобы я мог его принять.