You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Rest Controller生成的二维码展示到AngularJS页面?

解决AngularJS展示后端返回的二维码图片问题

看起来你遇到的核心问题是没有正确处理后端返回的图片字节数据,导致前端无法识别并渲染。下面我会一步步帮你排查问题,并给出可行的解决方案:

首先,明确后端返回的数据类型

你的Rest Controller返回的是"缓冲图片数据"(应该是byte[]或二进制流),而AngularJS的$http默认会把响应解析为JSON,这会导致二进制图片数据被损坏。所以第一步要修改请求配置,告诉AngularJS正确处理二进制数据。


方案1:使用Blob + ObjectURL(推荐,性能更好)

这种方式不需要把二进制数据转成base64,直接用浏览器的ObjectURL来渲染图片,内存占用更低。

步骤1:修改AngularJS控制器的请求代码

$http.post("../rest/a/save", {}, {
  responseType: 'blob' // 关键:告诉$http返回Blob类型的二进制数据
}).then(function(response){
  // 创建Object URL,供img标签使用
  $scope.qrcodeUrl = URL.createObjectURL(response.data);
});

// 重要:控制器销毁时释放ObjectURL,避免内存泄漏
$scope.$on('$destroy', function() {
  if ($scope.qrcodeUrl) {
    URL.revokeObjectURL($scope.qrcodeUrl);
  }
});

步骤2:HTML中直接使用img标签

<img ng-src="{{qrcodeUrl}}" alt="二维码" />

方案2:转换为Base64字符串渲染

如果你更习惯用base64的方式,可以把二进制数据转成base64字符串,再拼接成data URI。

步骤1:修改控制器代码

$http.post("../rest/a/save", {}, {
  responseType: 'arraybuffer' // 接收ArrayBuffer类型的二进制数据
}).then(function(response){
  // 将ArrayBuffer转换为Uint8数组
  var byteArray = new Uint8Array(response.data);
  // 转成base64字符串
  var base64Str = btoa(String.fromCharCode.apply(null, byteArray));
  // 拼接成图片的data URI
  $scope.qrcodeBase64 = 'data:image/png;base64,' + base64Str;
});

步骤2:HTML中使用img标签

<img ng-src="{{qrcodeBase64}}" alt="二维码" />

修复你原来的自定义指令

如果你想继续使用av-qr指令,需要修改指令逻辑,让它能处理二进制数据或base64字符串,而不是把数据当成DOM元素:

app.directive('avQr', function() { 
    return { 
        restrict: 'E', 
        template: '<img alt="二维码">',
        scope: { 
            imageData: '<' // 接收Blob或base64字符串
        }, 
        link: function(scope, elem, attr) { 
            var imgElement = elem.find('img');
            
            // 监听imageData变化,更新图片
            scope.$watch('imageData', function(newData) {
                if (!newData) return;
                
                // 先清理旧的资源
                var oldSrc = imgElement.attr('src');
                if (oldSrc && oldSrc.startsWith('blob:')) {
                    URL.revokeObjectURL(oldSrc);
                }
                
                if (newData instanceof Blob) {
                    // 处理Blob类型数据
                    imgElement.attr('src', URL.createObjectURL(newData));
                } else if (typeof newData === 'string' && newData.startsWith('data:image/')) {
                    // 处理base64的data URI
                    imgElement.attr('src', newData);
                }
            });
            
            // 指令销毁时清理资源
            scope.$on('$destroy', function() {
                var src = imgElement.attr('src');
                if (src && src.startsWith('blob:')) {
                    URL.revokeObjectURL(src);
                }
            });
        } 
    } 
});

使用修改后的指令

如果用方案1的Blob数据:

$http.post("../rest/a/save", {}, {responseType: 'blob'}).then(function(response){
  $scope.qrcodeData = response.data;
});
<av-qr image-data="qrcodeData"></av-qr>

如果用方案2的base64数据:

<av-qr image-data="qrcodeBase64"></av-qr>

为什么你原来的方式不行?

  • 你的自定义指令中angular.element(scope.image)是错误的:scope.image是后端返回的二进制数据,不是DOM元素,直接append肯定无法渲染。
  • <div ng-bind-html="qrcode"></div>:qrcode是二进制数据,不是HTML字符串,而且即使转成HTML,也需要用$sce.trustAsHtml信任内容,否则AngularJS会过滤掉。
  • <img data-ng-src='data:image/png;base64,{{qrcode}} />:qrcode是原始字节数据,不是base64字符串,所以拼接后无法被识别。

内容的提问来源于stack exchange,提问作者Manoj Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:04:37