给img标签自定义请求头

1,215 阅读1分钟

问题描述

在使用oss资源时遇到资源要加防盗链的需求,某种原因referer字段线上环境存在丢失,选择另一种解决方案是数字签名+请求头添加Authorization字段实现。

图片资源是放在的img标签的src属性,这个请求是不受我们控制的,要加请求头字段的话,需要手动发起请求。

项目

vite + vue3

封装一个公用的myImg组件,列一下注意点

  1. 图片可能有点击事件
  2. 图片有不同的样式显示
  3. 此项目为h5,ios端需要使用https协议,所以有一个http替换为https的操作
  4. 原生ajax发起请求并自定义设置请求头
  5. img标签有个默认的边框,需要处理掉

完整代码

<template>
  <img @click="click" :style="imgStyle" ref="myImg" />  // 点2
</template>

<script>
import { ref, onMounted } from "vue";
export default {
  props: {
    imgSrc: {
      type: String,
      default: ""
    },
    imgStyle: {
      type: Object,
      default: () => {}
    }
  },
  setup(props, ctx) {
    let myImg = ref(null);
    let imgSrc = ref(props.imgSrc);
    let imgStyle = ref(props.imgStyle);
    onMounted(() => {
      let request = new XMLHttpRequest();
      request.responseType = "blob";
      request.open("get", imgSrc.value.replace("http:", "https:"), true); // 点3
      request.setRequestHeader("Authorization", "tph");  // 点4
      request.onreadystatechange = () => {
        if (
          request.readyState == XMLHttpRequest.DONE &&
          request.status == 200
        ) {
          myImg.value.src = URL.createObjectURL(request.response);
          myImg.value.onload = () => {
            URL.revokeObjectURL(myImg.value.src);
          };
        }
      };
      request.send(null);
    });
    return {
      myImg,
      imgStyle,
      click() {
        ctx.emit("click");  // 点1
      }
    };
  }
};
</script>

<style lang="less" scoped>
img[src=""],              /* 点5 */
img:not([src]) {
  opacity: 0;
}
</style>

TIPS

其实同理的其他类型的资源也是可以这样处理

也可以使用axios这些库