SAP B1, Bagaimana cara menampilkan Gambar yang diambil dari ItemImage?

10

Saya mengambil gambar dari SAP B1 Service Layer. Di tukang pos, saya dapat melihatnya sebagai image/png, tetapi ada masalah menampilkannya.

Apa cara yang benar untuk menunjukkannya <img />?

require(fetchedImage) - tidak bekerja


Saya telah membuat Fungsi Cloud untuk mengambil gambar dan meneruskannya ke klien, tetapi saya tidak yakin bagaimana melakukannya.

Memiliki benda super aneh seperti ini

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

Tidak tahu cara mengirimkannya res.send(IMAGE IN PNG)sehingga saya bisa melihat mendapatkan gambar di sisi klien.

Memeriksa base64konversi tetapi saya tidak yakin bagaimana menggunakannya.


Memperbarui

Permintaan tukang pos: (Ini berfungsi dengan baik)

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

Header : SessionId: MEMINTA SAYA KETIKA ANDA MENCOBA

Untuk beberapa alasan, kami tidak dapat mengambil Gambar langsung di Front-End dan perlu membuat middleware sehingga kami melakukannya di Firebase Cloud Function

Jadi di sini adalah fungsi yang mengambil gambar dan tidak tahu cara melewatinya.

Inilah fungsi di 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);

Dan kami mendapat respons seperti ini:

{status: 200,

statusText: 'OK',

tajuk:

{ 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' ] },

konfigurasi:

{ url:

data:

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

INI SUPER PANJANG DAN PERGI UNTUK 80-100 baris lagi

Jika Anda ingin menguji, Anda dapat menggunakan yang berikut ini:

Tukang pos:

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

tubuh: {"productId": "test"}

ProductId yang valid adalah: 1. "RR000102" 2. "test" 3. "RR000101"

Dhaval Jardosh
sumber
1
Sudahkah Anda mengatur jenis konten di backendres.set({'Content-Type': 'image/png'});
C.Gochev
1
Ya saya mencobanya juga, itu memberikan gambar yang rusak.
Dhaval Jardosh
1
apakah kamu menyimpannya di suatu tempat?
C.Gochev
1
Tidak, tidak, apakah ada cara untuk menyelesaikannya tanpa itu?
Dhaval Jardosh
1
Anda dapat proksi secara langsung const request = require('request')dan dalam ruterequest.get(url).pipe(res);
C.Gochev

Jawaban:

4

Jika Anda ingin menggunakan gambar secara dinamis, Anda harus mengambil gambar segera setelah komponen dipasang dan masukkan setelahnya. Gambar yang diambil kemudian harus disimpan dalam keadaan komponen dan dimasukkan dari sana dalam attrbut src dari tag img. Dengan asumsi Anda sudah dapat mengambil gambar, kode di bawah ini akan berfungsi.

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>
    );   
  }
}
Tarif
sumber
1
Saya tidak bisa mengambil langsung di ComponentDidMount, karena saya perlu membuat fungsi kustom di Server-Side dan untuk itu, saya melakukannya melalui fungsi Cloud.
Dhaval Jardosh
1
Itu tidak memungkinkan saya untuk mengambil di sisi klien, katanya header ilegal melewati mengambil / aksioma, ketika saya melakukannya dari Bereaksi.
Dhaval Jardosh
3

Inilah solusi terdekat yang bisa saya gunakan. Pada dasarnya yang saya coba adalah untuk mengambil gambar dan kemudian mengubahnya menjadi gumpalan pada klien sehingga Anda dapat membuatnya menjadi. objectURLKode diperbarui mengalirkan gambar sebagai buffer dan mengkonsumsinya pada klien kemudian mengubahnya menjadi objectURL dan menetapkan ke gambar src

Kode server:

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)

Kode klien:

<!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.ochev
sumber
Hei satu hal yang saya lupa katakan, bahwa saya mendapatkan gambar di sini GET : https://su05.consensusintl.net/b1s/v1/ItemImages('test')/$value, tetapi ketika saya melewati hal yang sama, itu tidak berfungsi. Beri tahu saya jika Anda mendapatkan ide yang lebih baik, maaf jika saya mengganggu Anda.
Dhaval Jardosh
apresiasi kecil dari sisiku :)
Dhaval Jardosh
lihat kode yang diperbarui. ini adalah upaya terakhir saya. semoga kamu menemukan solusinya.
C.Gochev
0

Masalah ini telah diatasi.

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

Jadi kami dapat melihat gambar di sisi klien menggunakan

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

Dhaval Jardosh
sumber