大家好,我是1024小神,技术群 / 私活群 / 股票群 或 交朋友 都可以私信我。 如果你觉得本文有用,一键三连 (点赞、评论、关注),就是对我最大的支持~

因为项目要添加一个新的功能,就是在pad上的网页需要打开摄像头扫码的能力,而且是在局域网访问的,所以就需要后端地址启动在https的地址上,这个时候所有的静态资源都变成了https链接,这个时候一个unity同事在游戏中访问图片地址的时候就访问不了,有解决方案,但是要修改的地方有点多,但是扫码又必须使用https的链接,所以备选方案就是后端启动两个服务,一个http转为给游戏提供http的图片链接,https转为pad提供扫码能力。
但是这个时候问题就来了:pad + server + game 三者之间的通讯是使用proto协议传输的,其中就包含图片地址,这个图片地址是只有http链接字段的,不想再添加一个https的字段,会很麻烦,添加的话大家所有人都要修改代码,这个就只有我这个前端自己来解决了,那就是将所有图片链接中http替换为https,并将端口9091替换为9090,那全局那么多img标签呢,怎么做?
方案1:全局组件替换
创建一个全局的图片组建,然后将项目中的所有img标签改成这个全局组件,不推荐:因为要创建函数和全局组件,还要修改项目中所有的img标签,麻烦
javascript
<!-- components/SecureImg.vue -->
<template>
<img :src="secureSrc" v-bind="$attrs">
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
src: String
})
const secureSrc = computed(() => {
if (!props.src) return ''
return props.src.replace(/^http:\/\//i, 'https://')
})
</script>
然后在项目中全局注册:
javascript
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import SecureImg from './components/SecureImg.vue'
const app = createApp(App)
app.component('Img', SecureImg)
app.mount('#app')
方案2:使用Vue指令
创建一个指令,然后将所有img标签的src属性改为使用指令的方式。这个时候要改的就简单了,就是全局搜索<img src= 然后替换为 <img v-secure-src=即可实现。
javascript
// directives/secureSrc.js
export const secureSrc = {
beforeMount(el, binding) {
if (binding.value && typeof binding.value === 'string') {
el.src = binding.value.replace(/^http:\/\//i, 'https://')
}
},
updated(el, binding) {
if (binding.value && typeof binding.value === 'string') {
el.src = binding.value.replace(/^http:\/\//i, 'https://')
}
}
}
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import { secureSrc } from './directives/secureSrc'
const app = createApp(App)
app.directive('secure-src', secureSrc)
app.mount('#app')
如果img的src跟的是变量,直接使用指令跟上变量就可以了:
javascript
<template>
<div>
<!-- 静态字符串 -->
<img v-secure-src="'http://example.com/image1.jpg'" alt="image1">
<!-- 动态变量 -->
<img v-secure-src="imageUrl" alt="dynamic image">
<!-- 响应式数据 -->
<img v-secure-src="user.avatar" alt="user avatar">
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
// 响应式数据
const imageUrl = ref('http://example.com/image2.jpg')
const user = reactive({
avatar: 'http://example.com/avatar.jpg'
})
// 可以动态更新
setTimeout(() => {
imageUrl.value = 'http://another-domain.com/new-image.jpg'
}, 3000)
</script>
方案3:使用指令参数
可以通过参数的形式,将url地址传递到指令里面,然后在指令里面修改:
javascript
// directives/secureSrc.js
export const secureSrc = {
beforeMount(el, binding) {
if (binding.arg === 'url') {
updateSrc(el, binding.value)
}
},
updated(el, binding) {
if (binding.arg === 'url') {
updateSrc(el, binding.value)
}
}
}
function updateSrc(el, src) {
if (src && typeof src === 'string') {
el.src = src.replace(/^http:\/\//i, 'https://')
} else {
el.src = src || ''
}
}
使用方式:
javascript
<template>
<div>
<!-- 使用指令参数 -->
<img v-secure-src:url="dynamicImageUrl" alt="dynamic image">
<img v-secure-src:url="staticImageUrl" alt="static image">
</div>
</template>
<script setup>
import { ref } from 'vue'
const dynamicImageUrl = ref('http://example.com/dynamic.jpg')
const staticImageUrl = 'http://example.com/static.jpg'
</script>
方法4:支持修饰符的指令
javascript
// directives/secureSrc.js
export const secureSrc = {
beforeMount(el, binding) {
processSrc(el, binding)
},
updated(el, binding) {
processSrc(el, binding)
}
}
function processSrc(el, binding) {
const src = binding.value
let processedSrc = src
if (src && typeof src === 'string') {
// 强制HTTPS修饰符
if (binding.modifiers.https) {
processedSrc = src.replace(/^http:\/\//i, 'https://')
}
// 添加时间戳修饰符(避免缓存)
if (binding.modifiers.nocache) {
const separator = processedSrc.includes('?') ? '&' : '?'
processedSrc += `${separator}_t=${Date.now()}`
}
}
el.src = processedSrc || ''
}
使用方式:
javascript
<template>
<div>
<!-- 只启用HTTPS转换 -->
<img v-secure-src.https="imageUrl" alt="https only">
<!-- 同时启用HTTPS和去缓存 -->
<img v-secure-src.https.nocache="dynamicImage" alt="https and nocache">
</div>
</template>
<script setup>
import { ref } from 'vue'
const imageUrl = ref('http://example.com/image.jpg')
const dynamicImage = ref('http://example.com/dynamic.jpg')
</script>
推荐方案
使用方法3(指令参数) 最为清晰,因为:
语义明确:v-secure-src:url 清楚地表示这是处理URL的
避免冲突:不会影响其他属性的处理
易于扩展:可以添加其他参数处理不同场景
这样无论src是静态字符串还是动态变量,都能正确工作,并且在数据更新时自动响应变化。
大家好,我是1024小神,技术群 / 私活群 / 股票群 或 交朋友 都可以私信我。 如果你觉得本文有用,一键三连 (点赞、评论、关注),就是对我最大的支持~