Javascript 使用 http 获取图像或字节数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36152917/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get Image or byte data with http
提问by Supamiu
For a web application I need to get my images with an ajax request because we have signature + authentication on our API, so we can't get images using a simple <img src="myapi/example/145"/>
对于 Web 应用程序,我需要通过 ajax 请求获取我的图像,因为我们的 API 上有签名 + 身份验证,因此我们无法使用简单的方法获取图像 <img src="myapi/example/145"/>
Since we're using angular2, we obviously looked for blob or something like that, but as stated in static_response.d.ts
file:
由于我们使用的是 angular2,我们显然在寻找 blob 或类似的东西,但如static_response.d.ts
文件中所述:
/**
* Not yet implemented
*/
blob(): any;
So okay, I can't do it for now, I have to wait for thie feature to be implemented.
所以好吧,我现在不能这样做,我必须等待这个功能实现。
But problem is I can't wait so I need a hotfix or a little hack to be able to get image data from response and I'll be able to remove my hack and set the blob()
method call to be good when it will be implemented.
但问题是我等不及了,所以我需要一个修补程序或一些小技巧才能从响应中获取图像数据,并且我将能够删除我的 hack 并将blob()
方法调用设置为在实施时正确。
I tried this:
我试过这个:
export class AppComponent {
constructor(private api:ApiService, private logger:Logger){}
title = 'Tests api';
src='http://placekitten.com/500/200'; //this is src attribute of my test image
onClick(){ //Called when I click on "test" button
this.api.test().then(res => {
console.log(res._body);
var blob = new Blob([new Uint8Array(res._body)],{
type: res.headers.get("Content-Type")
});
var urlCreator = window.URL;
this.src = urlCreator.createObjectURL(blob);
});
}
}
with ApiService.test()
method:
用ApiService.test()
方法:
test():Promise<any> {
return this.http.get(this._baseUrl + "myapi/example/145", this.getOptions())
//getOptions() is just creating three custom headers for
//authentication and CSRF protection using signature
.toPromise()
.then(res => {
this.logger.debug(res);
if(res.headers.get("Content-Type").startsWith("image/")){
return res;
}
return res.json();
})
.catch(res => {
this.logger.error(res);
return res.json();
} );
}
But I don't get any image from it and logging the response data shows a big string which is image data.
但是我没有从中得到任何图像,并且记录响应数据显示了一个大字符串,它是图像数据。
Do you have a hack to achieve this?
你有黑客来实现这一目标吗?
回答by tschuege
It is not necessary to extend BrowserXhr
anymore. (Tested with angular 2.2.1)
RequestOptionsArgsnow has a property responseType: ResponseContentType
which can be set to ResponseContentType.Blob
没有必要再延长BrowserXhr
了。(用 angular 2.2.1 测试)
RequestOptionsArgs现在有一个responseType: ResponseContentType
可以设置为的属性ResponseContentType.Blob
Using DomSanitizer
使用 DomSanitizer
import {DomSanitizer} from '@angular/platform-browser';
This example also creates a sanitized url that can be bound to the src
property of an <img>
这个例子还创建了一个消毒URL可以绑定到src
的属性<img>
this.http.get(url, {
headers: {'Content-Type': 'image/jpg'},
responseType: ResponseContentType.Blob
})
.map(res => {
return new Blob([res._body], {
type: res.headers.get("Content-Type")
});
})
.map(blob => {
var urlCreator = window.URL;
return this.sanitizer.bypassSecurityTrustUrl(urlCreator.createObjectURL(blob));
})
回答by Cuzox
Using the new Angular HttpClient is really easy to achieve this. Going off of tschuege's approach, it would be:
使用新的 Angular HttpClient 非常容易实现这一点。脱离 tschuege 的方法,它将是:
return this._http.get('/api/images/' + _id, {responseType: 'blob'}).map(blob => {
var urlCreator = window.URL;
return this._sanitizer.bypassSecurityTrustUrl(urlCreator.createObjectURL(blob));
})
The key is to set the responseType as 'blob' so that it doesn't attempt to parse it as JSON
关键是将 responseType 设置为“blob”,这样它就不会尝试将其解析为 JSON
回答by Thierry Templier
I think that you missed to set the responseType
on your request. Right now it's a bit tricky because it's not supported.
我认为您错过了responseType
根据您的要求设置。现在它有点棘手,因为它不受支持。
The workaround would be to override the BrowserXhr
class to set the responseType
on the xhr
object itself...
解决方法是覆盖BrowserXhr
类以responseType
在xhr
对象本身上设置...
You could extend the BrowserXhr
:
你可以扩展BrowserXhr
:
@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
constructor() {}
build(): any {
let xhr = super.build();
xhr.responseType = 'arraybuffer';
return <any>(xhr);
}
}
and override the BrowserXhr
provider with the extended class:
并BrowserXhr
使用扩展类覆盖提供者:
bootstrap(AppComponent, [
HTTP_PROVIDERS,
provide(BrowserXhr, { useClass: CustomBrowserXhr })
]);
The problem is here that you don't override for all requests. At the bootstrap level, it will override everything. So you could provide it in a sub injector within the providers
attribute of the impacted component...
问题在于您不会覆盖所有请求。在引导级别,它将覆盖所有内容。因此,您可以providers
在受影响组件的属性内的子注入器中提供它...
Here is a working plunkr: https://plnkr.co/edit/tC8xD16zwZ1UoEojebkm?p=preview.
这是一个有效的 plunkr:https://plnkr.co/edit/tC8xD16zwZ1UoEojebkm ?p =preview 。
回答by VirginieLGB
This JSFiddle could help you: https://jsfiddle.net/virginieLGB/yy7Zs/936/
这个 JSFiddle 可以帮助你:https://jsfiddle.net/virginieLGB/yy7Zs/936/
The method is, as you wanted, creating a Blob from the URL provided
该方法是,如您所愿,从提供的 URL 创建一个 Blob
// Image returned should be an ArrayBuffer.
var xhr = new XMLHttpRequest();
xhr.open( "GET", "https://placekitten.com/500/200", true );
// Ask for the result as an ArrayBuffer.
xhr.responseType = "arraybuffer";
xhr.onload = function( e ) {
// Obtain a blob: URL for the image data.
var arrayBufferView = new Uint8Array( this.response );
var blob = new Blob( [ arrayBufferView ], { type: "image/jpeg" } );
var urlCreator = window.URL || window.webkitURL;
var imageUrl = urlCreator.createObjectURL( blob );
var img = document.querySelector( "#photo" );
img.src = imageUrl;
};
xhr.send();