SAP B1,如何显示从 ItemImage 获取的图像?
SAP B1, How to display fetched Image from ItemImage?
我正在从 SAP B1 服务层获取图像。
在邮递员中,我可以将其视为 image/png
,但显示时出现问题。
在 <img />
中显示它的正确方法是什么?
require(fetchedImage)
- 无效
我已经创建了一个 Cloud Function 来获取图像并将其传递给客户端,但我不知道该怎么做。
有一个像这样的超级奇怪的物体
data:
> '�PNGörönöu001aönöu0000öu0000öu0000örIHDRöu0000öu.........
不知道如何通过 res.send(IMAGE IN PNG)
传递它,所以我可以在客户端看到获取图像。
已检查 base64
转换,但我不确定如何使用它们。
更新
邮递员请求:(工作正常)
GET : https://su05.consensusintl.net/b1s/v1/ItemImages('test')/$value
Headers: SessionId: ASK ME WHEN YOU TRY
出于某种原因,我们无法在前端直接获取图像,需要创建一个中间件,所以我们在 Firebase Cloud Function
中进行
所以这是获取图像但不知道如何传递它的函数。
这是 Firebase 云函数中的函数:
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);
我们收到这样的回复:
{ status: 200,
statusText: 'OK',
headers:
{ 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:
data:
'�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
这太长了,还有 80-100 行
如果你想测试你可以使用以下:
邮递员:
POST: https://us-central1-rapid-replacement.cloudfunctions.net/getImageFromItems
body: {"productId":"test"}
有效的 productId 是:1."RR000102"2."test"3."RR000101"
如果要动态使用图片,必须在组件挂载后立即获取图片,然后再插入。然后应将获取的图片保存在组件的状态中,并从那里包含在 img 标签的 src 属性中。假设您已经可以获取图片,下面的代码应该可以工作。
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>
);
}
}
这是我找到的最接近可行的解决方案。基本上我尝试的是获取图像,然后在客户端将其转换为 blob,这样您就可以将其转换为 objectURL
。更新的代码将图像作为缓冲区流式传输并在客户端使用它,然后将其转换为objectURL 并分配给图像 src
服务器代码:
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)
客户代码:
<!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>
此问题已解决。
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;
};
所以我们可以使用
在客户端看到图像
<img src="data:image/png;base64,[BASE64-VALUE-HERE]"/>
我正在从 SAP B1 服务层获取图像。
在邮递员中,我可以将其视为 image/png
,但显示时出现问题。
在 <img />
中显示它的正确方法是什么?
require(fetchedImage)
- 无效
我已经创建了一个 Cloud Function 来获取图像并将其传递给客户端,但我不知道该怎么做。
有一个像这样的超级奇怪的物体
data:
> '�PNGörönöu001aönöu0000öu0000öu0000örIHDRöu0000öu.........
不知道如何通过 res.send(IMAGE IN PNG)
传递它,所以我可以在客户端看到获取图像。
已检查 base64
转换,但我不确定如何使用它们。
更新
邮递员请求:(工作正常)
GET : https://su05.consensusintl.net/b1s/v1/ItemImages('test')/$value
Headers: SessionId: ASK ME WHEN YOU TRY
出于某种原因,我们无法在前端直接获取图像,需要创建一个中间件,所以我们在 Firebase Cloud Function
所以这是获取图像但不知道如何传递它的函数。
这是 Firebase 云函数中的函数:
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);
我们收到这样的回复:
{ status: 200,
statusText: 'OK',
headers:
{ 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:
data:
'�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
这太长了,还有 80-100 行
如果你想测试你可以使用以下:
邮递员:
POST: https://us-central1-rapid-replacement.cloudfunctions.net/getImageFromItems
body: {"productId":"test"}
有效的 productId 是:1."RR000102"2."test"3."RR000101"
如果要动态使用图片,必须在组件挂载后立即获取图片,然后再插入。然后应将获取的图片保存在组件的状态中,并从那里包含在 img 标签的 src 属性中。假设您已经可以获取图片,下面的代码应该可以工作。
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>
);
}
}
这是我找到的最接近可行的解决方案。基本上我尝试的是获取图像,然后在客户端将其转换为 blob,这样您就可以将其转换为 objectURL
。更新的代码将图像作为缓冲区流式传输并在客户端使用它,然后将其转换为objectURL 并分配给图像 src
服务器代码:
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)
客户代码:
<!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>
此问题已解决。
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;
};
所以我们可以使用
在客户端看到图像
<img src="data:image/png;base64,[BASE64-VALUE-HERE]"/>