2017-08-02 49 views
0

我试图让使用Redux的可观测图像。如何使用redux-observable正确地获取二进制映像?

基于Microsoft Graph API,它返回所请求的照片的二进制数据。

我成功得到利用邮差图像(它显示的结果,因为它是二进制图像)。

然而,当我尝试使用redux-observable响应我总是null,并的responseType总是json不管我给了Content-Type的像image/jpegtext/plainapplication/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 
} 
+0

你需要提供一个接受头瓦特/二进制文件图像MIME类型?例如为什么json是响应类型? – Tim

+0

@蒂姆是的,这是一个很好的观点。基于[api](https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/profilephoto_get),我只需要提供'Authorization'。但是我实际上尝试为** Content-Type **添加'image/jpeg','text/plain','application/json',但** responseType **总是'json'。 –

+1

我相信这里的'Content-Type'只会影响请求,而不会影响响应。您应该在响应正文中获取图像的base64编码版本。你可以添加响应身体吗? –

回答

1

我想首先要确保它变得清晰,终极版,可观察到的和RxJS是两码事。这个问题实际上是一个RxJS问题,因为几乎所有的问题,你会遇到(使用终极版,可观察到即使),因为终极版,可观察到的小,真的推迟几乎一切惯用的Rx。这很重要,因为如果您提出问题,并将它们表述为Rx问题,您会发现更多的帮助和资源,因为它是一个更大的社区。希望这可以帮助!


如果您使用的是内置的RxJS V5 AJAX工具,您需要使用常规ajax()帮手,而不是速记ajax.get()之一。

然后你就可以提供responseType: 'arraybuffer'获取图像作为二进制数据:

​​

由于这个问题实际上是无关的终极版,可观察到的,这里有一个工作示例演示得到的二进制数据,然后创建一个<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); 
    }); 
1

当角4号楼的图形浏览器中,我遇到了同样的问题。在我们的例子中,请求图像时,我们必须将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有responseTyp的财产,所以我建议改变,但我不是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) 
); 
相关问题