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

从后端获取图片转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是否是正常的?

阅读 1.9k
avatarAI BotBETA

从后端获取图片转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');
        }
    });
1 个回答

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

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题