JS如何显示防盗链的外站图片技巧示例

 更新时间:2023年09月28日 08:36:22   作者:jsoncode  
通常在开发测试环节,一些资源图片会出现防盗链的错误提示,本文就通过前端基础技术,实现基本的图片跨站显示效果,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

防盗链的原理

  • 服务端通过请求头的request.headers.referer来判断是否是自己资源白名单的请求来源。
  • 如果referer=null,则无法判断来源,会正常显示图片。

所以基于以上理论,可以给图片创造一个没有referer的请求环境就可以实现了。

解决思路

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

实现过程

  • 创建一个base64临时资源,供iframe调用
  • 在临时资源中,请求图片
  • 图片加载完成后,修改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>

以上就是JS如何显示防盗链的外站图片的详细内容,更多关于JS显示防盗链的外站图片的资料请关注脚本之家其它相关文章!

相关文章

最新评论