在 Angular JS 中将图像 blob 应用于 src?

Applying image blob to src in Angular JS?

我有一些 API 提供图像的端点,但这些图像需要身份验证。我有一项服务 (authenticatedHttp),它是对 $http 的抽象并处理身份验证令牌管理。 (这已被确认有效,并且出于所有意图和目的也可能是 $http

我正在接收响应,获取一个 blob 并创建一个对象 URL。所有这些都有效。我已经检查了 blob,可以确认它是正确的。

当我尝试将 objectUrl 应用于 src 时出现问题。我尝试了一个简化的例子,使用了一个我知道有效的片段,没有身份验证。这在我的 Angular 应用程序中不起作用,但在 vanilla JS 中有效。

我对 ObjectUrl 了解不多,但如果它有所不同,当我检查空图像时,我发现它 src 是正确的,如果我单击 link 已创建(例如 blob:https://sub.domain.dev/de4db0e0-77c8-44bc-a934-0d270ab81687) 我被 ui-router 重定向。

为什么会发生这种情况,我该如何纠正?

app.directive('authenticatedSrc', ['authenticatedHttp', function (authenticatedHttp) {
  var directive = {
      link: link,
      restrict: 'A'
  };
  return directive;
  function link(scope, element, attrs) {
    var requestConfig = {
      cache: 'false'
    };
    authenticatedHttp.get(attrs.authenticatedSrc, requestConfig).then(function(response) {
      var objectUrl = window.URL.createObjectURL(new Blob([response.data], { type: 'image/png' }));
      attrs.$set('src', objectUrl);
    });
  }
}]);

response.data 的 return 类型是什么?它是 base64 编码的字符串吗? 当直接在 src 属性中提供时,img 标签可以很好地渲染 base64 编码的图像。 此外,请尝试 angularjs 的 $sce 服务来信任此对象 Url 作为有效的 Url。 $sce.trustAsURL(objectUrl) 同时添加到 src 属性。 更多信息 https://docs.angularjs.org/api/ng/service/$sce

下载二进制信息时,重要的是设置responseType:

app.directive('authenticatedSrc', ['authenticatedHttp', function (authenticatedHttp) {
  var directive = {
      link: link,
      restrict: 'A'
  };
  return directive;
  function link(scope, element, attrs) {
    var requestConfig = {
      //IMPORTANT
      responseType: 'blob',
      cache: 'false'
    };
    authenticatedHttp.get(attrs.authenticatedSrc, requestConfig).then(function(response) {
      //var objectUrl = window.URL.createObjectURL(new Blob([response.data], { type: 'image/png' }));
      var blob = response.data;
      attrs.$set('src', blob);
    });
  }
}]);

否则数据会因从 UTF-8 to DOMstring (UTF-16) 的转换而损坏。

有关详细信息,请参阅 MDN XHR API ResponseType

@Kaiido 也对,但这不是我的主要问题。

@georgeawg 解决了我的大部分问题,但我没有接受他的回答,因为他的实现(直接使用 blob 作为源)对我不起作用。

这是我的最终代码。

app.directive('authenticatedSrc', ['authenticatedHttp', function (authenticatedHttp) {
  var directive = {
      link: link,
      restrict: 'A'
  };
  return directive;
  function link(scope, element, attrs) {
    var requestConfig = {
      cache: 'false',
      responseType: 'blob'
    };
    authenticatedHttp.get(attrs.authenticatedSrc, requestConfig).then(function(response) {
      var reader = new window.FileReader();
      reader.readAsDataURL(response.data);
      reader.onloadend = function() {
        attrs.$set('src', reader.result);
      };
    });
  }
}]);