前后端以数据url的方式传递字节流

发布时间 2023-10-04 20:02:54作者: 斌哥的小弟

正常情况下通过字节流,将本地的一张图片渲染到前端(vue2):

后端:

String imagePath="图片路径";
        byte[] imageBytes= Files.readAllBytes(Paths.get(imagePath)); //获取文件字节
        String base64Image= Base64.getEncoder().encodeToString(imageBytes);//把这些图片的组成字节变成代表这个图片的字符串
        return ResponseEntity.ok(base64Image); 

 

前端:

<template>   <img :src="imageSrc">  </template>
<script>
import axios from 'axios'
export default {
  name: 'HelloWorld',
  data(){
    return{
      imageSrc:'', 
  }  },
methods: {
  getPhoto(){
     axios.post("/api/toGetPhoto")
    .then(response=>{
      console.log("response.data是"+response.data); 
      this.imageSrc='data:image/png;base64,'+response.data;}).catch(error=>{  alert("请求失败")  });  } },  }  </script>

 

运行之后,报错URL TOO LONG,而在控制台上可以看到response.data是一串特别长的字符串,而这个错误就是表示URL过长,超出了服务器能够处理的限制。HTTP协议对URL的长度是有限制的,不同的服务器对URL的最大长度限制可能会有所不同。当你发送的URL超过服务器限制时,服务器会返回"URL TOO LONG"错误。

 

解决方案:

 使用数据url来显示图片,而不是直接在'src'中传递过长的Base64字符串,数据url就是在'src'属性中直接包含图片的数据而不需要额外的网络请求,数据url的目的是将一些小的数据,直接嵌入到网页中,从而不用再从外部文件载入。

 

修改:

 

 this.imageSrc='data:image/png;base64,'+response.data;

上面说的那串很长的字符,其实是一张小图片,将这些字符复制黏贴到浏览器的地址栏中并转到,就能看到它了,其中data表示取得数据的协定名称,image/png 是数据类型名称,
base64 是数据的编码方法,逗号后面就是这个image/png文件base64编码后的数据。<img src="data:image/png;base64,dnvjsdbuiab...(很长的字符串)" />也能表示图片,不用http请求,浏览器不缓存。

 

像视频等其他文件也能通过这种数据url的方式进行见后端交互。