Angular Http:如何使用自定义标头调用图像?

22
在HTML视图中,图像会像这样显示:
<img ng-src="{{element.image.url}}"> 

element.image.url指向类似于/rest_api/img/12345678的URL。

这个工作得很好,图片被显示出来了。

现在,我添加了身份验证:

在用户进行身份验证之前,每个资源都会响应 HTTP 错误 401,包括图片。身份验证成功后,会将令牌放置在自定义标头中,并随着每个 $http 请求一起发送,允许访问资源:

$http.defaults.headers.common['Authorization'] = token; 

对于使用 $resource 加载的 Json 文件,这很好用。但是,经过身份验证后,直接链接到图像的状态码仍为 401。

如何使用自定义标头调用图像?

或者,您有任何建议我应该如何做到这一点。


1
你是如何处理服务器端的身份验证的?是使用cookie/sessionId还是基本身份验证?据我所知,对于非XHR请求(脚本、CSS、图像、视频等),您无法附加自定义标头。这些由浏览器处理,您可能能够在每个请求之前/之后以编程方式控制用户代理标头,但是这些请求传递的唯一数据包括基本数据和cookie。 - Cuong Vo
服务器端由Ez Publish REST API处理。有两个cookies: PHPSESSID和eZSESSID以及由Angular处理的令牌(OAUTH)。你的意思是,如果会话cookie已定义,那么图像调用应该可以工作了吗? - François Romain
我不知道Ez Publish是如何工作的,但是是的,这个想法是后端处理身份验证并在验证sessionId后返回图像。你的图像是否与你正在进行身份验证的主机在同一个主机上? - Cuong Vo
是的,图像位于同一主机上。 - François Romain
@EliranMalka 的原因是这些图片是内容,只应该由经过身份验证的用户查看(不允许直接访问)。 - François Romain
显示剩余2条评论
5个回答

12

此处所述,你可以使用angular-img-http-src(如果使用Bower,则运行bower install --save angular-img-http-src)。

如果您查看代码,它使用URL.createObjectURLURL.revokeObjectURL,这些在2016年4月19日仍为草案。因此,请检查您的浏览器是否支持它

为了使用它,在您的应用程序模块中将 'angular.img'声明为依赖项 (angular.module('myapp', [..., 'angular.img'])),然后在您的 HTML 中,您可以为<img>标记使用http-src属性。

在您的示例中,代码应为:<img http-src="{{element.image.url}}">

当然,这意味着您已经声明了一个拦截器,并使用$httpProvider.interceptors.push添加了您自定义的标头,或者您已经为每个请求静态设置了您的标头,使用$http.defaults.headers.common.MyHeader = 'some value';


1
感谢您提供这个有用的答案!浏览器兼容性链接、示例以及关于声明的提醒都非常有帮助。五星好评! - Rob Bailey
是的,我们需要一种方法来进行+10的投票,这是非常简单的问题,特别是如果您的资源是从托管在另一个域上的服务中提供的。 - Chris Schaller

9
有一个非常简单的答案。你应该使用:angular-img-http-src
问题: 您使用基于令牌的身份验证,并且需要从安全路由提供图像。
解决方案: 使用http-src而不是ng-src,它将使用$http服务获取图像-这意味着通过拦截器添加的Authorization标头将存在-然后构建一个Blob并将src设置为objectURL。
在我的项目中完美运行。

2
我遇到了同样的问题。 我找到的最好的解决方案是将授权令牌作为查询参数传递。
例如:
<img src="http://myhost.com/image/path?accessToken=123456789" >

这样,您就可以为REST消费者仅保护这些图像。

非常实用的方法 - Daniel Hilgarth

1
考虑URL为http://foo.com/bar.png 在您的控制器中,

angular.module('foo')
  .controller('fooCtrl', ['$sce',
    function($sce) {
      $scope.dataSrc = "http://foo.com/bar.png"
      $scope.src = $sce.trustAsResourceUrl($scope.dataSrc)
    }
  ])

在你的看法中,

<img ng-src="{{src}}" />

"

...似乎行得通。

"

@jayM 如果它解决了你的问题,请将答案标记为正确。 - dolftax

-1
据我所知,无法在资产请求(浏览器在呈现页面时加载的脚本、图像、媒体、CSS 文件)中传递附加标头。这完全由浏览器控制。只有在进行 XHR(AJAX)请求时才能修改标头。
我建议查看您的服务器端身份验证,看看是否有解决方案。

2
你可以向应用程序发出的任何请求添加自己的HTTP头。这包括在内容中的<img>元素... - François Romain
@desgnl - 该解决方案需要提升的权限才能访问XPCOM接口,而网页没有这个权限。 - Neil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接