如何在RestController返回大字符串字节并在AngularJS中显示为图片
解决RestController返回图片字符串到AngularJS的[$http:baddata]错误及图片显示问题
我来帮你搞定这个问题!你碰到的[$http:baddata]错误,核心原因是AngularJS默认会把后端响应当成JSON来解析,但你原来返回的是对应GIF图片的ISO-8859-1编码字符串,里面满是不可打印的特殊字符,完全不符合JSON格式,自然就触发了解析错误。
下面分后端和前端两部分给出具体的解决方法:
后端RestController正确实现:直接返回图片字节流
不要返回字符串,而是直接把图片的二进制数据输出到响应流,同时设置正确的HTTP头,让浏览器识别这是一张GIF图片。
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; @RestController @RequestMapping("/api/images") public class ImageController { @GetMapping("/generated-gif") public void getGeneratedGif(HttpServletResponse response) throws IOException { // 你的原始响应字符串 String responseString = "ë!!ëh$þë.ë (-0mÓæEÈRjqY-ÖÉr-Êjêתl-d@i¶`é¥ mÛzàMÄínþÎmÝÞmÞ®ßþmàná&&nÓ:mãêëã^írLî6ví^î³fî&r®Ù~®Â®ÛÜBìéöfêâÞ:@ëö-à ¸o¿ú¨üÒ¯ýf\"æïðò/þoè¬ { 0+0;0_ÆÌTðø6øïktðS§0 K® o# $ð[@?0t¬È'YpÓño0± íò8ø¥¥ÄFðd¾ÞFBùÁ¸éû&k%Jb<±hÁåJ?¤?| y®0Æp Ó0ãÀlÀÀXAðÿÀÿìðS° ñz±÷T? \"×<óq ÿ1ò ærhíû-×ïMèr®pTdEþkÎÀµÎ´ó # < Ø ¬´A=?³?às>»Xó@ôA«©dRøCCoÀC8ßDEFórlôØÊGÓáHÿÁÚ4tJ¯4 ´ôKCóO3XдM.Atâêô¤*4C;4Dï.B5 _ô×f´(õæ2µâSGµ$O5J«4K»´3k5rMsdXçôt ´Ëô@@ 0VPÀûûû<ü æü´öÀf(æo AFVüÅ?@ Dhp!C¹f¼Ø5\"þÇ%ymÊ-cÂIÓfN<}JÔ(R¥LBJÕêÕ¬ 8Ú -Ë&û\"øð xáÍ`r¨&2Ðá ¾xüI-bP`þ£ôJÈà@A&î è øÀèp»2ã*òAÃÉ:ü0 I4 Ud aÆfÀQG}L :î!a O¸?þ±pD.ü;Ç¢¢¯p7à+xArnA!HèòÀý#X¼ hV"; // 设置响应头:告诉浏览器这是GIF图片,并且在页面内显示(不是下载) response.setContentType("image/gif"); response.setHeader("Content-Disposition", "inline; filename=one.gif"); // 将字符串转成ISO-8859-1字节,写入响应流 OutputStream outputStream = response.getOutputStream(); outputStream.write(responseString.getBytes(StandardCharsets.ISO_8859_1)); outputStream.flush(); outputStream.close(); } }
关键说明:
- 直接操作
HttpServletResponse输出字节流,避免了Spring MVC自动把返回值序列化成JSON的过程。 Content-Type: image/gif让浏览器知道这是一张GIF图片,会直接渲染而不是当成文本处理。Content-Disposition: inline指定图片在页面内显示,如果你想让用户可以下载,改成attachment即可。
前端AngularJS实现:两种显示方式
方式一:直接用img标签(最简单推荐)
不需要写任何JS代码,直接用ng-src指向后端接口即可,浏览器会自动请求并渲染图片:
<img ng-src="/api/images/generated-gif" alt="生成的GIF图片">
方式二:通过$http获取(适合需要处理认证/额外逻辑的场景)
如果需要通过Angular的$http请求(比如要携带认证令牌),必须设置responseType: 'blob',告诉Angular不要解析成JSON,而是作为二进制Blob处理:
angular.module('myApp').controller('ImageController', ['$http', function($http) { var vm = this; $http.get('/api/images/generated-gif', { responseType: 'blob', // 关键:指定响应类型为二进制Blob // 如果需要认证,可以在这里设置headers,比如: // headers: { 'Authorization': 'Bearer ' + token } }) .then(function(response) { // 创建一个本地URL指向Blob对象,供img标签使用 vm.imageUrl = URL.createObjectURL(response.data); }) .catch(function(error) { console.error('获取图片失败:', error); }); }]);
对应的HTML:
<div ng-controller="ImageController as vm"> <img ng-src="{{vm.imageUrl}}" alt="生成的GIF图片"> </div>
为什么原来的方法会报错?
你之前直接返回字符串时,AngularJS默认会尝试把响应解析成JSON,但你的字符串包含大量非ASCII、不可打印的字符,完全不符合JSON语法规范,所以触发了[$http:baddata]错误。改成直接返回字节流后,浏览器和Angular都能正确识别这是图片数据,就不会有解析问题了。
内容的提问来源于stack exchange,提问作者nps
相关产品推荐
相关产品推荐

