后台的图片不显示
Images from backend are not displayed
我从 nestjs 后端传输到 angular 前端的图像没有出现在浏览器中。
我从前端向后端发送一个查询,其中包含服务器上文件的路径(例如:“C:\MyFolder\MyFile.png”),它将读取图像并发送一个流回到前端。然后前端会将 blob 转换为图像并将 img 元素的 src 属性设置为图像的 URL。
后端
控制器后台代码:
@HttpCode(201)
@Get(':imageUrl')
@Header('Content-Type', 'image/png')
getFile(@Param('imageUrl')imageUrl: string) {
imageUrl = atob(imageUrl);
return fs.createReadStream(imageUrl);
}
前端
语言选择器 ts 代码:
currentLanguage: ApplicationLanguage;
availableLanguages: ApplicationLanguage[];
constructor(private readonly _languageProvider: CultureProviderService,
private readonly _imageLoader: ImageService) {
this.currentLanguage = _languageProvider._currentLanguage;
_languageProvider.languageChanged.subscribe(
newLanguage => {
this.currentLanguage = newLanguage;
}
)
}
ngOnInit(): void {
this._languageProvider.getAllAvailableLanguages().subscribe(
(languages: ApplicationLanguage[]) => {
this.availableLanguages = languages;
languages.forEach((language: ApplicationLanguage) => {
this._imageLoader.getImage(language.flagIcon).subscribe(
imgBlob => {
this._imageLoader.createImageFromBlob(imgBlob).then(
result => {
language.image = result;
},
err => {
console.log(err);
}
)
}
);
});
},
err => {
console.log(err);
}
);
}
检索图像的服务:
constructor(private readonly _http: HttpClient,
private domSanitizer: DomSanitizer) { }
getImage(imageUrl: string): Observable<Blob> {
return this._http.get(`${environment.machineServerUrl}/file/${btoa(imageUrl)}`, { responseType: 'blob' });
}
createImageFromBlob(imageUrl: Blob): Promise<SafeUrl> {
return new Promise<SafeUrl>((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener(
"load",
() => {
resolve(this.domSanitizer.bypassSecurityTrustUrl(reader.result as string));
}
);
if (imageUrl) {
reader.readAsDataURL(imageUrl);
} else {
reject();
}
});
}
HTML:
<div>
<mat-selection-list (selectionChange)="changeLanguage($event)"
[multiple]="false">
<mat-list-option *ngFor="let language of availableLanguages"
[value]="language" [selected] ="isSelected(language)">
<img [src]="language.image" height="70px" width="70px" alt="Flag">
</mat-list-option>
</mat-selection-list>
</div>
我是不是做错了什么?是不是少了什么?
编辑:
解决方案感谢接受的答案
首先,nestjs版本需要升级到v8+:nest update --force。不幸的是,我的项目失败了,所以我删除了 dist、node_modules 和 package-lock.json,使用 CLI v8+ 创建了一个新的 nestjs 项目,并使用生成的 package.json 文件升级了项目。
然后,按照接受的答案中的建议更新控制器的代码以使用 StreamableFile
:
@HttpCode(201)
@Get(':imageUrl')
@Header('Content-Type', 'image/png')
getFile(@Param('imageUrl')imageUrl: string): StreamableFile {
imageUrl = Buffer.from(imageUrl, 'base64').toString();
const file = createReadStream(imageUrl);
return new StreamableFile(file);
}
如果您要返回流,则需要执行类似
的操作
@HttpCode(201)
@Get(':imageUrl')
@Header('Content-Type', 'image/png')
getFile(@Param('imageUrl')imageUrl: string, @Res() res: e.Response) {
imageUrl = atob(imageUrl);
return fs.createReadStream(imageUrl).pipe(res);
}
如果您使用的是 Nest v8,则可以使用 StreamableFile 并执行类似
的操作
@HttpCode(201)
@Get(':imageUrl')
@Header('Content-Type', 'image/png')
getFile(@Param('imageUrl')imageUrl: string, @Res() res: e.Response) {
imageUrl = atob(imageUrl);
return new StreamableFile(fs.createReadStream(imageUrl));
Nest 会在后台为您调用 .pipe(res)
我从 nestjs 后端传输到 angular 前端的图像没有出现在浏览器中。
我从前端向后端发送一个查询,其中包含服务器上文件的路径(例如:“C:\MyFolder\MyFile.png”),它将读取图像并发送一个流回到前端。然后前端会将 blob 转换为图像并将 img 元素的 src 属性设置为图像的 URL。
后端
控制器后台代码:
@HttpCode(201)
@Get(':imageUrl')
@Header('Content-Type', 'image/png')
getFile(@Param('imageUrl')imageUrl: string) {
imageUrl = atob(imageUrl);
return fs.createReadStream(imageUrl);
}
前端
语言选择器 ts 代码:
currentLanguage: ApplicationLanguage;
availableLanguages: ApplicationLanguage[];
constructor(private readonly _languageProvider: CultureProviderService,
private readonly _imageLoader: ImageService) {
this.currentLanguage = _languageProvider._currentLanguage;
_languageProvider.languageChanged.subscribe(
newLanguage => {
this.currentLanguage = newLanguage;
}
)
}
ngOnInit(): void {
this._languageProvider.getAllAvailableLanguages().subscribe(
(languages: ApplicationLanguage[]) => {
this.availableLanguages = languages;
languages.forEach((language: ApplicationLanguage) => {
this._imageLoader.getImage(language.flagIcon).subscribe(
imgBlob => {
this._imageLoader.createImageFromBlob(imgBlob).then(
result => {
language.image = result;
},
err => {
console.log(err);
}
)
}
);
});
},
err => {
console.log(err);
}
);
}
检索图像的服务:
constructor(private readonly _http: HttpClient,
private domSanitizer: DomSanitizer) { }
getImage(imageUrl: string): Observable<Blob> {
return this._http.get(`${environment.machineServerUrl}/file/${btoa(imageUrl)}`, { responseType: 'blob' });
}
createImageFromBlob(imageUrl: Blob): Promise<SafeUrl> {
return new Promise<SafeUrl>((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener(
"load",
() => {
resolve(this.domSanitizer.bypassSecurityTrustUrl(reader.result as string));
}
);
if (imageUrl) {
reader.readAsDataURL(imageUrl);
} else {
reject();
}
});
}
HTML:
<div>
<mat-selection-list (selectionChange)="changeLanguage($event)"
[multiple]="false">
<mat-list-option *ngFor="let language of availableLanguages"
[value]="language" [selected] ="isSelected(language)">
<img [src]="language.image" height="70px" width="70px" alt="Flag">
</mat-list-option>
</mat-selection-list>
</div>
我是不是做错了什么?是不是少了什么?
编辑:
解决方案感谢接受的答案
首先,nestjs版本需要升级到v8+:nest update --force。不幸的是,我的项目失败了,所以我删除了 dist、node_modules 和 package-lock.json,使用 CLI v8+ 创建了一个新的 nestjs 项目,并使用生成的 package.json 文件升级了项目。
然后,按照接受的答案中的建议更新控制器的代码以使用 StreamableFile
:
@HttpCode(201)
@Get(':imageUrl')
@Header('Content-Type', 'image/png')
getFile(@Param('imageUrl')imageUrl: string): StreamableFile {
imageUrl = Buffer.from(imageUrl, 'base64').toString();
const file = createReadStream(imageUrl);
return new StreamableFile(file);
}
如果您要返回流,则需要执行类似
的操作@HttpCode(201)
@Get(':imageUrl')
@Header('Content-Type', 'image/png')
getFile(@Param('imageUrl')imageUrl: string, @Res() res: e.Response) {
imageUrl = atob(imageUrl);
return fs.createReadStream(imageUrl).pipe(res);
}
如果您使用的是 Nest v8,则可以使用 StreamableFile 并执行类似
的操作@HttpCode(201)
@Get(':imageUrl')
@Header('Content-Type', 'image/png')
getFile(@Param('imageUrl')imageUrl: string, @Res() res: e.Response) {
imageUrl = atob(imageUrl);
return new StreamableFile(fs.createReadStream(imageUrl));
Nest 会在后台为您调用 .pipe(res)