SAP B1, Como exibir a imagem buscada da ItemImage?

10

Estou buscando uma imagem do SAP B1 Service Layer. No carteiro, posso vê-lo como image/png, mas há um problema para exibi-lo.

Qual é a maneira correta de mostrá-lo <img />?

require(fetchedImage) - não funciona


Criei uma função de nuvem para buscar a imagem e transmiti-la ao cliente, mas não sei como fazê-lo.

Ter um objeto super estranho mais ou menos assim

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

Não sei como passar res.send(IMAGE IN PNG)para que eu possa ver uma imagem no lado do cliente.

base64Conversão marcada, mas não sei como usá-los.


Atualizar

Pedido do Carteiro: (Isso está funcionando bem)

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

Cabeçalhos : SessionId: PERGUNTE-ME QUANDO TENTAR

Por alguma razão, não podemos buscar a imagem diretamente no Front-End e precisamos criar um middleware, por isso estamos fazendo isso em Firebase Cloud Function

Então, aqui está a função que busca a imagem e não sabe como transmiti-la.

Aqui está a função na 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);

E estamos recebendo uma resposta como esta:

{status: 200,

statusText: 'OK',

cabeçalhos:

{ 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:

dados:

\ N \ u001a \ n \ u0000 \ u0000 \ u0000 \ rIHDR \ u0000 \ u0000 \ u0000 \ u0000 \ u0000 \ u0000 \ u0000 \ u0000 \ u0000 \ u0000 \ u0000 \ u0000 \ u0000 \ u00006 \ u001fS \ u0000 \ u0000 \ u0000 \ u0019tEXtSoftware \ u0000Adobe ImageReadyq e <\ u0000 \ u0000 \ u0003hiTXtXML: com.adobe.xmp \ u0000 \ u0000 \ u0000 \ u0000 \ u0000

ISSO É MUITO LONGO E DÁ MAIS 80-100 linhas

Se você deseja testar, pode usar o seguinte:

Carteiro:

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

body: {"productId": "test"}

Os productId válidos são: 1. "RR000102" 2. "test" 3. "RR000101"

Dhaval Jardosh
fonte
11
Você definiu o tipo de conteúdo no backres.set({'Content-Type': 'image/png'});
C.Gochev
11
Sim, eu tentei isso também, dá uma imagem quebrada.
Dhaval Jardosh 21/01
11
você os salva em algum lugar?
C.Gochev 21/01
11
Não, não estou, existe uma maneira de fazê-lo sem isso?
Dhaval Jardosh 21/01
11
Você pode const request = require('request')request.get(url).pipe(res);
procurá-

Respostas:

4

Se você quiser usar imagens dinamicamente, precisará buscá-las assim que o componente estiver montado e insira-o depois. A imagem buscada deve ser salva no estado do componente e incluída a partir daí no atributo src da tag img. Supondo que você já possa buscar a imagem, o código abaixo deve funcionar.

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
fonte
11
Não consigo buscar diretamente no ComponentDidMount, pois preciso criar uma função personalizada no lado do servidor e, por isso, estou fazendo isso através da função Cloud.
Dhaval Jardosh
11
Não está permitindo que eu busque no lado do cliente, diz cabeçalhos ilegais passados ​​em buscas / axios, quando eu faço isso no React.
Dhaval Jardosh 21/01
3

Aqui está a solução mais próxima que eu vim. Basicamente, o que eu tentei é buscar a imagem e transformá-la em um blob no cliente para que você possa transformá-lo em um objectURLcódigo. src

Código do servidor:

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)

Código do cliente:

<!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
fonte
Ei, uma coisa que esqueci de lhe dizer, que recebo uma imagem aqui GET : https://su05.consensusintl.net/b1s/v1/ItemImages('test')/$value, mas quando passo a mesma coisa, não está funcionando. Deixe-me saber se você tiver uma idéia melhor, desculpe se estou incomodando.
Dhaval Jardosh
pequena apreciação do meu lado :)
Dhaval Jardosh
veja o código atualizado. essa foi minha tentativa final. Espero que encontre uma solução.
C.Gochev 26/01
0

Este problema foi resolvido.

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;
};

Portanto, podemos ver a imagem no lado do cliente usando

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

Dhaval Jardosh
fonte