vue中img加载图片在请求头添加token

7,290 阅读2分钟

3333.png

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

需求

在加载图片的时候需要在请求头中加上token信息,后端返回二进制流,将二进制流以图片的形式显示在页面中

请求头加token思考

一般加载图片会用到img标签,添加src属性,如下所示:

<img src="imgUrl" />

但是因为需要在get请求头中加入token信息,不能直接将后台返回的图片url直接添加到src 后端返回二进制流,我们需要将二进制流以图片的形式显示在页面中

看到二进制,可以将responseType 设置为 blob

通过查阅MDN文档,要实现此功能需要用到以下方法:

URL.createObjectURL()

URL.createObjectURL()  静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。

URL.revokeObjectURL()

URL.revokeObjectURL() 静态方法用来释放一个之前已经存在的、通过调用 URL.createObjectURL() 创建的 URL 对象。当你结束使用某个 URL 对象之后,应该通过调用这个方法来让浏览器知道不用在内存中继续保留对这个文件的引用了。

基于以上知识,我们这里可以将这个功能封装成这个通用的组件,以便于日后多次在项目中使用

请求加token代码实现

基于vue2 实现

// 模板
<template>
    <img ref="authImg" />
</template>

// js
props:{
    imgUrl:String,
    authToken:String
},
// 结合具体业务需求添加
watch:{
    imgUrl(){
        this.getImgUrl();
    }
},
methods:{
    getImgUrl(){
          Object.defineProperty(Image.prototype,"imgurl",{
                  configurable:true,
                  writable:true,
                  enumerable:true
          })
          let request = new XMLHttpRequest();
          request.responseType = "blob";
          request.open("get",this.imgUrl,true);
          request.setRequestHeader('token',this.authToken);
          let imgRef = this.$ref.authImg;
          request.onreadystatechange = e => {
              if(request.readyState == XMLHttpRequest.DONE && request.status == 200){
                  imgRef.src = URL.createObjectURL(request.response); // 将生成的blob对象的值赋值给img的src属性
                  imgRef.onLoad = () => {
                      URL.revokeObjectURL(imgRef.src); // 在图片加载完成后释放
                  }
              }
          }
          request.send(null)
    }
}

基于vue3 + ts实现

// 模板
<template>
    <img ref="authImg" />
</template>

// js
props:{
    imgUrl:String,
    authToken:String
}
setup(props){

    onMounted(getImgUrl)
    
    const authImg = ref<any>();
    const getImgUrl = () => {
          Object.defineProperty(Image.prototype,"imgurl",{
                  configurable:true,
                  writable:true,
                  enumerable:true
          })
          let request = new XMLHttpRequest();
          request.responseType = "blob";
          request.open("get",props.imgUrl,true);
          request.setRequestHeader('token', props.authToken);
          
          request.onreadystatechange = e => {
              if(request.readyState == XMLHttpRequest.DONE && request.status == 200){
               authImg.value.src = URL.createObjectURL(request.response); // 将生成的blob对象的值赋值给img的src属性
              authImg.value.onLoad = () => {
                      URL.revokeObjectURL(authImg.value.src); // 在图片加载完成后释放
                  }
              }
          }
          request.send(null)
    }
    
    // 结合具体业务需求添加
    watch(()=> props.imgUrl,() => {
        getImgUrl()
    })
    
    return {
        authImg
     }
}

组件使用

<auth-img :imgUrl="xxx" :authToken="xxx"></auth-img>

总结

对处理二进制流有了基础的认识,以上算是实现了基础的功能,其实这里可以到以下知识点,后续会用其他文章进行输出

  1. 图片是如何加载与渲染的
  2. 在项目中应该如何优化图片资源
  3. 图片预加载,懒加载的原理以及实现