[英]How to GET binary image correctly using redux-observable?
I am trying to GET image using redux-observable. 我试图使用redux-observable获取图像。
Based on Microsoft Graph API , it returns binary data of the requested photo. 基于Microsoft Graph API ,它返回所请求照片的二进制数据。
I succeed getting the image using Postman (it shows the image in the result since it is binary). 我成功使用Postman获取图像(它显示结果中的图像,因为它是二进制)。
However, when I try to use redux-observable , response I got is always null
, and responseType is always json
no matter what I give for Content-Type like image/jpeg
, text/plain
, application/json
. 但是,当我尝试使用redux-observable时 ,我得到的响应总是为
null
,并且无论我为Content-Type提供什么样的响应,它都是json
如image/jpeg
, text/plain
, application/json
。
export const getAvatarEpic = (action$, store) =>
action$
.ofType(GET_AVATAR)
.mergeMap(action =>
ajax
.get(
'https://graph.microsoft.com/v1.0/me/photo/$value',
{
// 'Content-Type': 'image/jpeg',
'Authorization': 'Bearer ' + myToken
}
)
.do(res => console.log(res)) // <- the result
.map(getAvatarSucceed)
.catch(getAvatarFailed)
);
Here is what I got. 这就是我得到的。 Maybe I should use something else instead of
ajax.get
? 也许我应该使用别的东西而不是
ajax.get
?
{
"originalEvent": {
"isTrusted": true
},
"xhr": {},
"request": {
"async": true,
"crossDomain": false,
"withCredentials": false,
"headers": {
"Authorization": "Bearer hereIsMyToken",
"X-Requested-With": "XMLHttpRequest"
},
"method": "GET",
"responseType": "json",
"timeout": 0,
"url": "https://graph.microsoft.com/v1.0/me/photo/$value"
},
"status": 200,
"responseType": "json",
"response": null
}
I want to first make sure it becomes clear that redux-observable and RxJS are separate things. 我想首先确保redux-observable和RxJS是分开的东西。 This question is actually an RxJS question, as is nearly all questions you'll come across (even when using redux-observable) since redux-observable is small and really defers almost everything to idiomatic Rx.
这个问题实际上是一个RxJS问题,因为几乎所有你会遇到的问题(即使使用redux-observable)也是如此,因为redux-observable很小,并且几乎把所有东西都推迟到惯用的Rx。 This is important because when asking questions if you present and phrase them as just Rx questions you'll find much more help and resources since it's a larger community overall.
这一点很重要,因为在提问时如果你提出问题并将它们简称为Rx问题,你会发现更多的帮助和资源,因为它是一个更大的社区。 Hope this helps!
希望这可以帮助!
If you're using the built-in ajax utilities for RxJS v5, you'll need to use the regular ajax()
helper, not the shorthand ajax.get()
one. 如果您正在为RxJS v5使用内置的ajax实用程序,则需要使用常规的
ajax()
帮助程序,而不是简写的ajax.get()
。
Then you can provide responseType: 'arraybuffer'
to get the image as a binary data: 然后你可以提供
responseType: 'arraybuffer'
来获取图像作为二进制数据:
export const getAvatarEpic = (action$, store) =>
action$
.ofType(GET_AVATAR)
.mergeMap(action =>
ajax({
url: 'https://graph.microsoft.com/v1.0/me/photo/$value',
headers: {
'Authorization': 'Bearer ' + myToken
},
responseType: 'arraybuffer'
})
.do(res => console.log(res)) // <- the result
.map(getAvatarSucceed)
.catch(getAvatarFailed)
);
Since this question actually is unrelated to redux-observable, here's a working example demonstrating getting the binary data and then creating an <img>
with it: 由于这个问题实际上与redux-observable无关,这里有一个工作示例,演示获取二进制数据然后用它创建
<img>
:
https://jsbin.com/mimijot/edit?js,output https://jsbin.com/mimijot/edit?js,output
import { ajax } from 'rxjs/observable/dom/ajax';
ajax({
url: 'https://proxy.apisandbox.msdn.microsoft.com/svc?url=https%3A%2F%2Fgraph.microsoft.com%2Fv1.0%2Fme%2Fphoto%2F%24value',
headers: { 'Authorization': 'Bearer {token:https://graph.microsoft.com/}' },
responseType: 'arraybuffer'
})
.subscribe(res => {
console.log(res);
const buffer = res.response;
const blob = new Blob([buffer], { type: 'image/jpeg' });
const url = URL.createObjectURL(blob);
const img = document.createElement('img');
img.src = url;
document.body.appendChild(img);
});
When building the Graph explorer with Angular 4, I encountered the same issue. 使用Angular 4构建Graph explorer时,遇到了同样的问题。 In our case, when requesting images we have to set the
responseType
parameter to ArrayBuffer
instead of the default value. 在我们的例子中,在请求图像时,我们必须将
responseType
参数设置为ArrayBuffer
而不是默认值。
https://github.com/microsoftgraph/microsoft-graph-explorer/blob/master/src/app/graph-service.ts#L54 https://github.com/microsoftgraph/microsoft-graph-explorer/blob/master/src/app/graph-service.ts#L54
case "GET": // for all JSON requests to Graph
return this.http.get(query, {headers: requestHeaders}).toPromise();
case "GET_BINARY": // when fetching images
return this.http.get(query, {responseType: ResponseContentType.ArrayBuffer, headers : requestHeaders}).toPromise();
And then when processing the response, we get the blob URL and set the image element's src: 然后在处理响应时,我们获取blob URL并设置image元素的src:
let blob = new Blob( [ result.arrayBuffer() ], { type: "image/jpeg" } );
let imageUrl = window.URL.createObjectURL( blob );
const imageResultViewer = <HTMLImageElement>document.getElementById("responseImg");
imageResultViewer.src = imageUrl;
It looks like Rx.DOM.ajax
has the responseType property, so I recommend changing that but I'm not an RxJS expert! 看起来
Rx.DOM.ajax
有responseType属性,所以我建议改变它,但我不是RxJS专家! More info about XMLHttpRequest.responseType
can be found at https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType 有关
XMLHttpRequest.responseType
更多信息, 请访问https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType
Final code: 最终代码:
export const getAvatarEpic = (action$, store) =>
action$
.ofType(GET_AVATAR)
.mergeMap(action =>
aja:@{
url: 'https://graph.microsoft.com/v1.0/me/photo/$value',
responseType: 'arraybuffer',
headers: {
// 'Content-Type': 'image/jpeg',
'Authorization': 'Bearer ' + store.getState().auth.token
}
})
.map(getAvatarSucceed)
.catch(getAvatarFailed)
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.