郑重正告:本文止于技术钻研,请勿在本人的生产环境应用别人图片资源。
通常在开发测试环节,一些资源图片会呈现防盗链的谬误提醒,本文就通过前端根底技术,实现根本的图片跨站显示成果。
防盗链的原理:
- 服务端通过申请头的
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>
此文为自己原创翻新文章,转发请注明起源。