Не удается отобразить изображение base64, полученное из mongodb, в React ERR_INVALID_URL

#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 и удалил все преобразования на стороне интерфейса, и это сработало. Спасибо. Отредактируйте свой ответ, чтобы я мог его принять.