关于图片:如何显示防盗链的外站图片

12次阅读

共计 1822 个字符,预计需要花费 5 分钟才能阅读完成。

郑重正告:本文止于技术钻研,请勿在本人的生产环境应用别人图片资源。

通常在开发测试环节,一些资源图片会呈现防盗链的谬误提醒,本文就通过前端根底技术,实现根本的图片跨站显示成果。

防盗链的原理:

  1. 服务端通过申请头的 request.headers.referer 来判断是否是本人资源白名单的申请起源。
  2. 如果 referer=null, 则无奈判断起源,会失常显示图片。

所以基于以上实践,能够给图片发明一个没有 referer 的申请环境就能够实现了。

解决思路:

通过 iframe 来实现无 referer 的申请环境。

实现过程:

  1. 创立一个 base64 长期资源,供 iframe 调用
  2. 在长期资源中,申请图片
  3. 图片加载实现后,批改 iframe.height=img.height

源码

base64 长期资源:

const src = 'http://test.com/test.png';

const html = `data:text/html;base64,${btoa(`<img src="${src}"/>`)}`

<iframe src="html"></iframe>

应用 ResizeObserver 监听图片高度

因为以后 iframe 里只有一个图片,所以监听 body 高度即可(body 有默认 margin,前面须要革除款式)。(ResizeObserver API)

var ro = new ResizeObserver(entries => {for (let entry of entries) {const data = {height: entry.contentRect.height};
    window.parent?.postMessage({...data, window: 'parent'}, '*')
    window.top?.postMessage({...data, window: 'top'}, '*')
  }
})
ro.observe(document.body)

window.addEventListener("message", e => {if (e.data.window === 'parent') {iframe.style.height = e.data.height + 'px'}
}, false)

残缺代码 (vue3 setup ts)

<script setup lang="ts">
import {onMounted, ref, withDefaults} from 'vue'

interface IProps {
    src: string;
    id?: string
}

const props = withDefaults(defineProps<IProps>(), {});
const iframe = ref(null)

onMounted(() => {if (iframe.value) {const html = `<style>body{margin:0;}</style>
        <img src="${props.src}" style="display:block"/>
        <script>
            var ro = new ResizeObserver(entries => {for (let entry of entries) {const data = {height: entry.contentRect.height, id: "${props.id || props.src}"};
                    window.parent?.postMessage({...data, window: 'parent'}, '*')
                    window.top?.postMessage({...data, window: 'top'}, '*')
                }
            })
            ro.observe(document.body)
        <\/script>`
        iframe.value.src = `data:text/html;base64,${btoa(html)}`
    }

    window.addEventListener("message", e => {if (e.data.window === 'parent' && e.data.id === props.src && iframe.value) {iframe.value.style.height = e.data.height + 'px'}
    }, false)
})
</script>

<template>
    <iframe ref="iframe" style="display: block; border: 0;"></iframe>
</template>

此文为自己原创翻新文章,转发请注明起源。

正文完
 0