如何使用 redux-observable 正确获取二进制图像?
How to GET binary image correctly using redux-observable?
我正在尝试使用 redux-observable 获取图像。
基于Microsoft Graph API,它returns所请求照片的二进制数据。
我使用 Postman 成功获取了图像(它在结果中显示图像,因为它是二进制的)。
但是,当我尝试使用 redux-observable、response 时,我得到的总是 null
和 responseType 总是 json
无论我为 Content-Type 提供什么,例如 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)
);
这是我得到的。也许我应该用别的东西代替 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
}
在使用Angular 4构建Graph explorer时,我遇到了同样的问题。在我们的例子中,当请求图像时,我们必须将 responseType
参数设置为 ArrayBuffer
而不是默认值。
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();
然后在处理响应时,我们得到 blob URL 并设置图像元素的 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;
看起来 Rx.DOM.ajax
具有响应类型 属性,所以我建议更改它,但我不是 RxJS 专家!有关 XMLHttpRequest.responseType
的更多信息,请访问
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType
最终代码:
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)
);
我想首先确定 redux-observable 和 RxJS 是分开的东西。这个问题实际上是一个 RxJS 问题,几乎所有你会遇到的问题(即使在使用 redux-observable 时)也是如此,因为 redux-observable 很小并且实际上将几乎所有内容都推迟到惯用的 Rx。这很重要,因为当你提问时,如果你将它们作为 Rx 问题来呈现和表达,你会发现更多的帮助和资源,因为它是一个更大的社区。希望这对您有所帮助!
如果您使用 RxJS v5 的内置 ajax 实用程序,则需要使用常规 ajax()
帮助程序,而不是 shorthand ajax.get()
一个.
然后你可以提供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)
);
由于这个问题实际上与 redux-observable 无关,这里有一个工作示例演示如何获取二进制数据,然后用它创建一个 <img>
:
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);
});
我正在尝试使用 redux-observable 获取图像。
基于Microsoft Graph API,它returns所请求照片的二进制数据。
我使用 Postman 成功获取了图像(它在结果中显示图像,因为它是二进制的)。
但是,当我尝试使用 redux-observable、response 时,我得到的总是 null
和 responseType 总是 json
无论我为 Content-Type 提供什么,例如 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)
);
这是我得到的。也许我应该用别的东西代替 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
}
在使用Angular 4构建Graph explorer时,我遇到了同样的问题。在我们的例子中,当请求图像时,我们必须将 responseType
参数设置为 ArrayBuffer
而不是默认值。
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();
然后在处理响应时,我们得到 blob URL 并设置图像元素的 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;
看起来 Rx.DOM.ajax
具有响应类型 属性,所以我建议更改它,但我不是 RxJS 专家!有关 XMLHttpRequest.responseType
的更多信息,请访问
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType
最终代码:
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)
);
我想首先确定 redux-observable 和 RxJS 是分开的东西。这个问题实际上是一个 RxJS 问题,几乎所有你会遇到的问题(即使在使用 redux-observable 时)也是如此,因为 redux-observable 很小并且实际上将几乎所有内容都推迟到惯用的 Rx。这很重要,因为当你提问时,如果你将它们作为 Rx 问题来呈现和表达,你会发现更多的帮助和资源,因为它是一个更大的社区。希望这对您有所帮助!
如果您使用 RxJS v5 的内置 ajax 实用程序,则需要使用常规 ajax()
帮助程序,而不是 shorthand ajax.get()
一个.
然后你可以提供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)
);
由于这个问题实际上与 redux-observable 无关,这里有一个工作示例演示如何获取二进制数据,然后用它创建一个 <img>
:
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);
});