SAP B1, Comment afficher l'image récupérée depuis ItemImage?

10

Je récupère une image de SAP B1 Service Layer. Dans Postman, je peux le voir comme image/png, mais il y a un problème d'affichage.

Quelle est la bonne façon de l'afficher <img />?

require(fetchedImage) - ne fonctionne pas


J'ai créé une fonction cloud pour récupérer l'image et la transmettre au client, mais je ne sais pas comment le faire.

Avoir un objet super bizarre quelque chose comme ça

 data:
>     '�PNGörönöu001aönöu0000öu0000öu0000örIHDRöu0000öu.........

Je ne sais pas comment le passer res.send(IMAGE IN PNG)pour que je puisse voir obtenir une image côté client.

base64Conversion vérifiée mais je ne sais pas comment les utiliser.


Mise à jour

Postman Request: (Cela fonctionne bien)

OBTENIR: https://su05.consensusintl.net/b1s/v1/ItemImages ('test') / $ value

En-têtes : SessionId: DEMANDEZ-MOI LORSQUE VOUS ESSAYEZ

Pour une raison quelconque, nous ne pouvons pas récupérer l'image directement dans Front-End et devons créer un middleware, nous le faisons donc dans Firebase Cloud Function

Voici donc la fonction qui récupère l'image et ne sait pas comment la passer.

Voici la fonction dans Firebase Cloud Function:

if (!req.body.productId) {
      res.status(400).send({ error: "productId is required" });
      return;
    }

    console.log("Starting the process");

    const productId = req.body.productId;

    const login = await Auth.login();
    const fetchedImg = await ItemMaster.getImage(login["SessionId"], productId);

    //Here in the fetchedImg, we're getting some data like
    res
      .status(200)
      .set("Content-Type", "image/png")
      .send(fetchedImg);

Et nous obtenons une réponse comme celle-ci:

{statut: 200,

statusText: 'OK',

en-têtes:

{ server: 'nginx',

  date: 'Wed, 22 Jan 2020 03:52:22 GMT',

  'content-type': 'image/png',

  'transfer-encoding': 'chunked',

  connection: 'close',

  dataserviceversion: '3.0',

  'content-disposition': 'inline; filename="rr-96600.png"',

  vary: 'Accept-Encoding',

  'set-cookie': [ 'ROUTEID=.node2; path=/b1s' ] },

config:

{ url:

Les données:

' PNG \ r \ n \ u001a \ n \ u0000 \ u0000 \ u0000 \ rIHDR \ u0000 \ u0000 \ u0000 \ u0000 \ u0000 \ u0000 \ b \ u0002 \ u0000 \ u0000 \ u0000 \ u0006 \ u001fS \ u0000 \ u0000 \ u0000 \ u0019tEXtSoftware \ u0000Adobe ImageReadyq e <\ u0000 \ u0000 \ u0003hiTXtXML: com.adobe.xmp \ u0000 \ u0000 \ u0000 \ u0000 \ u0000

C'EST SUPER LONG ET VA POUR 80-100 lignes supplémentaires

Si vous souhaitez tester, vous pouvez utiliser les éléments suivants:

Facteur:

POST: https://us-central1-rapid-replacement.cloudfunctions.net/getImageFromItems

body: {"productId": "test"}

ProductId valide sont: 1. "RR000102" 2. "test" 3. "RR000101"

Dhaval Jardosh
la source
1
Avez-vous défini le type de contenu dans le backendres.set({'Content-Type': 'image/png'});
C.Gochev
1
Oui j'ai essayé ça aussi, ça donne une image cassée.
Dhaval Jardosh
1
les enregistrez-vous quelque part?
C.Gochev
1
Non, je ne le suis pas, y a-t-il un moyen de le faire sans cela?
Dhaval Jardosh
1
Vous pouvez le proxy directement const request = require('request')et dans l'itinérairerequest.get(url).pipe(res);
C.Gochev

Réponses:

4

Si vous souhaitez utiliser des images de manière dynamique, vous devez récupérer les images dès que le composant est monté et l'insérer ensuite. L'image récupérée doit ensuite être enregistrée dans l'état du composant et incluse à partir de là dans le src attrbut de la balise img. En supposant que vous pouvez déjà récupérer l'image, le code ci-dessous devrait fonctionner.

import React, { Component } from "react";

export default class ComponentWithFetchedImage extends Component {
  constructor() {
    super();
    this.state = { image: undefined };   
  }

  componentDidMount() {
    let fetch_url = "https://picsum.photos/200";   // Insert your fetch url here
    fetch(fetch_url)
      .then(res => res.blob())
      .then(blob => URL.createObjectURL(blob))
      .then(url => this.setState({ image: url }))
      .catch(err => console.log(err));
  }

  render() {
    return (
      <div className="component">
        <img src={this.state.image} alt="" />
      </div>
    );   
  }
}
Taric
la source
1
Je ne peux pas récupérer directement dans ComponentDidMount, car j'ai besoin de créer une fonction personnalisée côté serveur et pour cela, je le fais via la fonction Cloud.
Dhaval Jardosh
1
Cela ne me permet pas de récupérer du côté client, cela dit que les en-têtes illégaux sont passés dans fetch / axios, quand je le fais depuis React.
Dhaval Jardosh
3

Voici le plus proche d'une solution de travail que je suis venue. Fondamentalement, ce que j'ai essayé est de récupérer l'image, puis de la transformer en une goutte sur le client afin que vous puissiez en faire unobjectURL code. src

Code serveur:

const http = require('http')
const axios = require('axios')
const fs = require('fs')
const stream = require('stream')
const server = http.createServer(function(req, res) {
  if (req.url === '/') {


    res.setHeader("Access-Control-Allow-Origin", "*");
    axios.post(
      "https://su05.consensusintl.net/b1s/v1/ItemImages('test')/$value", {
        responseType: "blob"
      }).then(function(resp) {
      console.log(resp.data)
      const buf_stream = new stream.PassThrough()
      buf_stream.end(Buffer.from(resp.data))
      buf_stream.pipe(res.end())
    }).catch(err => console.log(err))
  }
})


server.listen(3500)

Code client:

<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
  <title></title>
</head>

<body>
  <img style="width:200px; height:200px" />
  <script>

  const img = document.getElementsByTagName("IMG")
  fetch('http://localhost:3500').then(function(response) {
    console.log(response)
    return response.body
  }).then(function(data) {
    console.log(data)
    const reader = data.getReader()
     return new ReadableStream({
    start(controller) {
      return pump();
      function pump() {
        return reader.read().then(({ done, value }) => {
          // When no more data needs to be consumed, close the stream
          if (done) {
              controller.close();
              return;
          }
          // Enqueue the next data chunk into our target stream
          controller.enqueue(value);
          return pump();
        });
      }
    }
  })
})
  .then(stream => new Response(stream))
  .then(response => response.blob())
  .then(blob => URL.createObjectURL(blob))
  .then(url => img[0].src = url)
  .catch(err => console.error(err));
    </script>
</body>

</html>
C.Gochev
la source
Hé, une chose que j'ai oublié de vous dire, c'est que j'obtiens une image ici GET : https://su05.consensusintl.net/b1s/v1/ItemImages('test')/$value, mais quand je passe la même chose, ça ne marche pas. Faites-moi savoir si vous avez une meilleure idée, désolé si je vous dérange.
Dhaval Jardosh
petite appréciation de mon côté :)
Dhaval Jardosh
voir le code mis à jour. ce fut ma dernière tentative. j'espère que vous trouverez une solution.
C.Gochev
0

Ce problème a été résolu.

const getImage = async (sessionId, ItemCode) => {
  console.log("fetching image");
  let result = {};

  result = await axios.get(
    `${settings.url}${endpoints.ItemImages}('${ItemCode}')/$value`,
    { 
      headers: {Cookie: `B1SESSION=${sessionId}`},
      responseType: "arraybuffer" } 
    ).then(response => Buffer.from(response.data, 'binary').toString('base64'));

  //Here we're returning base64 value of Image
  return result;
};

Nous pouvons donc voir l'image du côté client en utilisant

<img src="data:image/png;base64,[BASE64-VALUE-HERE]"/>

Dhaval Jardosh
la source