问题描述
在使用oss资源时遇到资源要加防盗链的需求,某种原因referer字段线上环境存在丢失,选择另一种解决方案是数字签名+请求头添加Authorization字段实现。
图片资源是放在的img标签的src属性,这个请求是不受我们控制的,要加请求头字段的话,需要手动发起请求。
项目
vite + vue3
封装一个公用的myImg组件,列一下注意点
- 图片可能有点击事件
- 图片有不同的样式显示
- 此项目为h5,ios端需要使用https协议,所以有一个http替换为https的操作
- 原生ajax发起请求并自定义设置请求头
- 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这些库