当前位置: 首页 > 知识库问答 >
问题:

java - 从后端获取图片,但是blob不起作用,请问可能有哪些原因?

暴绪
2024-02-27

从后端获取图片转blob为什么失败?用unit8array转换显示大小为0 但是后端图片资源是获取成功的 可以正常预览 这可能是什么原因?前端是vue3 后端是springboot3.2.2 java版本是21
后端返回代码如下:

public byte[] getImages(String URL) throws IOException {        try (FileInputStream inputStream = new FileInputStream(new File(FilePath + URL))) {            byte[] bytes = new byte[inputStream.available()];            inputStream.read(bytes, 0, inputStream.available());            return bytes;        }    }

前端请求代码如下:

  const config = {      headers: {        Authorization: `Bearer ${this.$store.getters.getToken}`,        responseType: "arraybuffer",        accept: "image/jpeg",      },    };    send      .get(`/images/avatars/${this.$store.getters.getAvatar}`, config)      .then((response) => {        console.log(response.data);        const uint8Array = new Uint8Array(response.data);        console.log(uint8Array);        const blob = new Blob([response.data], { type: "image/jpeg" });        console.log(blob);        const url = window.URL.createObjectURL(blob);        this.avatarURL = url;      });

前端网络返回资源如下:
前端打印的信息:
网页和地址栏预览图片不显示:

纠缠了ai几个小时,搜索了与我类似的情况,尝试不使用accept,或者把responseType的"blob"换成"arraybuffer",不使用responseType,以及把arraybuffer格式化成Uint8Array,把URL.createObjectURL换成window.URL.createObjectURL,但是都不起左右
补充:看到ai的回答,打印了一下response.data的类型,是string,但是我后台返回的是byte[],请求头填的responseType是"blob",没一个对的上,这是否是正常的?另外还打印了一下arraybuffer和blob的类型,发现是对象,这就没办法参考了,c语言里面string是拿char[]模拟的,所以这返回的类型是string是否是正常的?

共有2个答案

洪越泽
2024-02-27

误打误撞弄好了,没有通过axios发送请求,而是直接把请求地址给img src,之前也试过,但是那时应该是把:src写成src了,没有绑定,所以请求没有被devServer proxy代理,我还以为图片元素的地址不能被代理呢,虽然依旧不清楚为什么,明明我是按照搜索到的方法写的,blob就是不行,但是问题貌似解决了,如果有大佬可以给出原因,欢迎解答

赫连永怡
2024-02-27

从后端获取图片转blob失败的可能原因有很多,以下是一些可能的原因:

  1. 后端返回的数据格式不正确:如果后端返回的不是二进制数据,而是其他格式的数据,那么前端将无法将其转换为blob。你需要确保后端返回的是二进制数据。
  2. 数据量过大:如果后端返回的数据量过大,可能会导致前端无法一次性将所有数据转换为blob。你可以尝试分批次读取数据,并逐批次转换为blob。
  3. 数据损坏或不完整:如果后端返回的数据在传输过程中被损坏或不完整,那么前端将无法将其转换为blob。你需要确保数据在传输过程中没有损坏或被截断。
  4. 网络问题:如果网络连接不稳定或中断,可能会导致前端无法从后端获取完整的数据,从而无法转换为blob。你需要确保网络连接稳定可靠。
  5. 浏览器兼容性问题:不同的浏览器可能对Blob和ArrayBuffer的处理方式有所不同,可能会导致转换失败。你需要确保你的代码兼容各种浏览器。

在你的情况中,我看到你在后端使用了inputStream.available()来读取数据,这个方法可能会返回文件的大约大小,但并不一定是完整的文件大小。另外,你返回的bytes可能没有被正确处理,这可能会导致前端无法将其转换为blob。

我建议你尝试以下修改:

  1. 替换inputStream.available()inputStream.read()方法来读取数据,并确保读取完整的数据。
  2. 返回字节数组时,使用return bytes;而不是return inputStream;
  3. 在前端处理响应时,检查响应的数据类型是否为ArrayBuffer或Blob,然后再进行转换。

这是一个修改后的后端代码示例:

public byte[] getImages(String URL) throws IOException {    try (FileInputStream inputStream = new FileInputStream(new File(FilePath + URL))) {        byte[] bytes = new byte[inputStream.available()];        inputStream.read(bytes); // 读取整个文件        return bytes;    }}

这是一个修改后的前端代码示例:

const config = {    headers: {        Authorization: `Bearer ${this.$store.getters.getToken}`,        responseType: "blob", // 使用blob作为响应类型    },};send    .get(`/images/avatars/${this.$store.getters.getAvatar}`, config)    .then((response) => {        if (response.data instanceof Blob) { // 检查响应数据是否为Blob类型            const blob = response.data; // 如果为Blob类型,则直接使用响应数据创建Blob对象            console.log(blob);            const url = window.URL.createObjectURL(blob);            this.avatarURL = url;        } else if (response.data instanceof ArrayBuffer) { // 如果响应数据为ArrayBuffer类型,则使用ArrayBuffer创建Blob对象            const uint8Array = new Uint8Array(response.data); // 将ArrayBuffer转换为Uint8Array类型            const blob = new Blob([uint8Array], { type: "image/jpeg" }); // 使用Uint8Array创建Blob对象            console.log(blob);            const url = window.URL.createObjectURL(blob); // 创建Blob对象的URL            this.avatarURL = url;        } else { // 如果响应数据既不是Blob类型也不是ArrayBuffer类型,则抛出错误或进行其他处理            console.error('Invalid response data type');        }    });
 类似资料:
  • 我写这个类是为了帮助从我的android项目的MySQL数据库中获取数据,但每次我运行应用程序时,它都会崩溃,有人能告诉我我的代码出了什么问题吗?我对此是新的,所以任何帮助都将非常感谢。 以下是错误消息所说的内容。 04-15 18:46:58.058 158 37-15837/com.example.tomb3.data e/androidruntime:致命异常:main process:co

  • 每当我试图从Intent获取uri时,它只是从图像选取器中选择一个图像,它在这里不起作用,这是我的代码。请尽快回答 这是日志: I/Error: java.lang.SecurityException: Permission Denial: read com.android.providers.media.MediaProvider uri content://media/external/ima

  • 阿里云oss如果是私有的图片,获取的时候能不能获取处理的图片,原图太大,能不能获取缩略图。 获取前面得url之后在后面添加图片处理参数,不可以?x-oss-process=image/resize,h_100,m_lfit 还是说私有的只能获取原图

  • 本文向大家介绍请问Spring中Bean的作用域有哪些?相关面试题,主要包含被问及请问Spring中Bean的作用域有哪些?时的应答技巧和注意事项,需要的朋友参考一下 考察点:框架 参考回答: 在Spring的早期版本中,仅有两个作用域:singleton和prototype,前者表示Bean以单例的方式存在;后者表示每次从容器中调用Bean时,都会返回一个新的实例,prototype通常翻译为原

  • 问题内容: 我试图在HashMap中找到一个键。我可以使用’get’打印选定的键,但是在if语句中使用’containsKey’时,找不到该键。 我知道该键存在于Map中,但它一直返回false。有什么想法的人吗? 我的代码: 这是Location类的代码: 问题答案: 您必须确保该类已正确实现其和方法(文档)。也就是说,如果两个对象实际上相等,则它们应该共享一个公共哈希码,并且它们的方法应该返回

  • 问题内容: 我想描述一下AOP有效参与应用程序设计的可能情况。到目前为止,我所遇到的是: 伐木相关 安全检查 交易管理 调整旧版应用程序 还要别的吗? (不一定是基于Spring的基于代理的AOP,而是JBoss AOP。) 问题答案: 我可以举两个使用它的示例: 在JMX中自动注册对象以进行远程管理。如果使用我们的注释对一个类进行注释,则我们可以通过一个方面来监视该类的新实例,并将其自动注册到J