如何从静态后端路径在 Angular 中显示图像?

Posted

技术标签:

【中文标题】如何从静态后端路径在 Angular 中显示图像?【英文标题】:How to display an image in Angular from a static backend path? 【发布时间】:2020-03-01 23:48:06 【问题描述】:

我在后端有一条路径,用于保存我的图像。 我可以从 mongo 获取路径并以角度重现它,但是,当我使用带有 src 绑定的标签时,它不会显示图像和任何错误:

组件内的路径:

this.profileService.getImg().subscribe(res => this.imagePath = res['img']);

控制台日志的返回:

console.log(this.imagePath);

http://localhost:3000/avatars/5db84cdf4c6efe073864f9e7.jpeg

html标签:

<img [src]="imagePath">

我尝试了在其他帖子中找到的几种方法,但都无法成功。 知道发生了什么以及如何解决这个问题?

更新和更多详情

在服务器端,我通过这种方式从 mongo 返回路径:

router.get('/:id', (req, res, next) => 
    Avatar.getAvatarById(req.params.id, (err, avatar) => 
        if(err) throw err;
        if(!avatar)
            return res.json(success: false, msg: 'No avatars found');
        
        res.json(
            success: true,
            avatar: avatar
        );
    );
);

Avatar.getAvatarById 是:

module.exports.getAvatarById = function(id, callback)
    const query =  avatar: $regex: ".*"+id+".*" 
    Avatar.findOne(query, callback);

我正在像这样公开头像路径:

app.use('/avatars', express.static('avatars'));

当我尝试通过在浏览器中点击http://localhost:3000/avatars/5db84cdf4c6efe073864f9e7.jpeg 来访问路径时,它会返回 json 而不是渲染图像。


 "success":true,
 "avatar": 
     "_id":"5dc17fc9f383424158c59754", 
     "avatar":"http://localhost:3000/avatars/5db84cdf4c6efe073864f9e7.jpeg","__v":0
 

还尝试通过使用 bypassSecurityTrustResourceUrl 来克服安全性并使用 *ngIf 来显示 url 存在时。

this.photoUrl = this.sanitizer.bypassSecurityTrustUrl(res['avatar']['avatar']);

<img *ngIf="photoUrl" [src]="photoUrl">

它不返回任何错误并且仍然不显示图像。

如果我尝试通过点击bypassSecurityTrustUrl 函数内的路径进行测试,并删除 *ngIf,它会返回:

null:1 GET http://localhost:4200/null 404 (Not Found)

【问题讨论】:

嗨迭戈。您是否将图像文件夹公开为静态文件夹并将其连接到/avatars?现在您只能从后端获取图像路径,但您没有执行任何步骤来公开该文件夹的内容(至少从您共享的代码中).. 【参考方案1】:

使用属性绑定应该可行:

 <img [src]="imagePath">

但你也可以尝试字符串插值

 <img src="imagePath">

【讨论】:

我都做了,但没有任何反应。 @DiegodeLima 您是否尝试将图像类型放入 URL 中?并检查您是否能够看到图像?只需将其放入 URl localhost:3000/avatars/5db84cdf4c6efe073864f9e7.jpeg 并告诉我们您看到了什么 看看问题。当我尝试它时,我刚刚用退货更新了它【参考方案2】:

您可以从 Angular 项目中的资产文件夹中静态加载图像。您也可以从后端静态检索图像。您可以通过使用 bypassSecurityTrustResourceUrl

来克服 Angular 的安全性

环境.ts

export const environment = 
  production: false,
  apiURL: 'http://localhost:8080/your-api/v1',
  imageUrl: '/assets/images/yourImage',
;

component.html

<img [src]="imageUrl">

component.ts

photoUrl: SafeResourceUrl;
  ngOnInit() 
    this.urlService.siteProfile.subscribe(s => 
      this.siteProfile = s;
      if(s != null) 
        this.photoUrl = this.sanitizer.bypassSecurityTrustResourceUrl(`$this.apiUrl/image-directory/your-pic?id`);
      
    );

【讨论】:

Ian 我做到了,但它返回 null:1 GET localhost:4200/null404(未找到)。即使我在 bypassSecurityTrustResourceUrl 函数中手动输入路径。【参考方案3】:

在您的贡献之后,我可以解决这个问题。 但问题不在前端,而实际上在后端。 但是,您的贡献对改进我的代码有很大帮助,因此我将把功劳归功于我可以实施或遵循我最终解决方案中的建议的每个人。

即使是我没有引用的那些人,我也非常感谢您花时间帮助我!

第一。感谢 @HenryDev

您是否尝试将图像类型放入 URL 中?并检查你是否 能看到图像吗?把它放在 URL 里 localhost:3000/avatars/5db84cdf4c6efe073864f9e7.jpeg 告诉我们什么 你看

在我尝试之后,我开始认为我的后端有问题,因为这个尝试的返回是 json 而不是图像渲染。

第二。致 @Thatkookooguy

使用特定的 res.sendFile:

app.get('/avatars/:name', function (req,
res, next)    const fileName = req.params.name;  
res.sendFile(fileName, options, function (err)  /* ... */ ); );

在后端,我使用路由查找保存在数据库中的头像,路径相同'/avatars/:id'。所以每次我尝试访问它时,优先级是路由。

因此,当我尝试通过在浏览器上点击路径来访问图像时,它会重新调整 json 文件而不是显示图像。

解决方案

所以,解决方案是替换路由调用函数获取图片列表!

但是,正如我告诉你的,我在这里得到了很多提示,这让我有机会改进我的代码:

第三。致 @Ian Halfpenny

您可以通过使用 Angular 来克服安全问题 绕过SecurityTrustResourceUrl

所以我使用 bypassSecurityTrustResourceUrl 替换了我的代码。

第四。感谢 @dota2pro

使用 *ngIf 在链接加载后显示图像。 (它是 编辑和删除。所以,很抱歉没有展示你的原作 贡献) 现在我通过*ngIf="avatar"之前的测试在我的html中显示

【讨论】:

【参考方案4】:

你试过了吗

<img [attr.src]="imagePath">

或者如果更改检测是这里的问题:

this.imagePath$ = this.profileService.getImg().pipe(
  map(res => res['img']),
);

<img [src]="imagePath$ | async">

【讨论】:

已经试过了。但它返回一个错误:GET localhost:4200/null 404 (Not Found)【参考方案5】:

您需要将文件从您的node.js 服务器公开到您的前端。现在,听起来您只是将路径字符串公开给客户端,而不是文件本身。

您可以通过在服务器上定义 static folder 来保存所有静态文件或通过定义路径并转到您想要检索该文件的任何文件夹来使用 res.sendFile 公开特定文件来做到这一点。

使用静态文件夹:

// connect the avatars folder as the `/avatars` server sub path
app.use('/avatars', express.static('avatars'));

使用特定的res.sendFile:

app.get('/avatars/:name', function (req, res, next) 
  const fileName = req.params.name;
  res.sendFile(fileName, options, function (err)  /* ... */ );
);

取决于您的所有文件是否都位于一个位置,或者用户是否将照片上传到私人位置,您需要使用其中一种方法将文件发送到浏览器,以便浏览器可以访问它。

【讨论】:

我已经以同样的方式暴露了它。但是会使用 res.sendFile 方式进行测试并返回结果 尝试使用 res.sendFile 但没有返回任何不同的结果。【参考方案6】:

在我的系统中,我们使用图像src 标签的servlet URL,该servlet 从图像返回base64 字符串,没有任何问题。

【讨论】:

我已经使用 *ngIF 进行了验证,并通过尝试显示内容进行了测试,它返回了带有路径的字符串

以上是关于如何从静态后端路径在 Angular 中显示图像?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Firebase Storage 获取图像并在 Angular 2 ngFor 中显示它们

如何将 Angular Material 图标资产路径与 Django 模板集成?

在 Visual Studio 的 ASP.NET Core + Angular 2 模板上设置图像路径

从 MongoDB 在 Angular.js 中显示图像

动态图像路径未显示在 Angular 7 的 [style.background-image] 属性中

我如何在 Angular 中写博客组件?