欢迎光临白事网
详情描述

1. 使用代理服务器

// 简单示例:通过自己的服务器转发
const proxyImage = (url) => {
  return `https://your-proxy-server.com/proxy?url=${encodeURIComponent(url)}`;
};

// 使用
const imageUrl = 'https://external-site.com/image.jpg';
document.getElementById('img').src = proxyImage(imageUrl);

2. 使用第三方代理服务

// CORS Anywhere(需要先请求权限)
const corsProxy = 'https://cors-anywhere.herokuapp.com/';

// 或使用其他公共服务
const proxyServices = [
  'https://api.codetabs.com/v1/proxy?quest=',
  'https://corsproxy.io/?',
  'https://api.allorigins.win/raw?url='
];

function loadWithProxy(url) {
  const proxyUrl = proxyServices[0] + encodeURIComponent(url);
  return fetch(proxyUrl).then(response => response.blob());
}

3. 修改 Referrer Policy

<!-- HTML 方式 -->
<img src="image.jpg" referrerpolicy="no-referrer">

<!-- 或 -->
<img src="image.jpg" referrerpolicy="origin">

<!-- 或使用 meta 标签 -->
<meta name="referrer" content="no-referrer">
// JavaScript 动态设置
const img = new Image();
img.referrerPolicy = 'no-referrer';
img.src = 'https://external-site.com/image.jpg';

// 或为所有图片设置
document.querySelectorAll('img').forEach(img => {
  img.referrerPolicy = 'no-referrer';
});

4. 使用 fetch 并控制 headers

async function loadImageWithoutReferrer(url) {
  try {
    const response = await fetch(url, {
      headers: {
        'Referrer-Policy': 'no-referrer'
      },
      mode: 'cors' // 注意:目标服务器需支持 CORS
    });

    const blob = await response.blob();
    const objectURL = URL.createObjectURL(blob);
    return objectURL;
  } catch (error) {
    console.error('加载失败:', error);
    return null;
  }
}

// 使用
loadImageWithoutReferrer('https://external.com/image.jpg')
  .then(url => {
    if (url) {
      document.getElementById('img').src = url;
    }
  });

5. 使用 Base64 编码

// 通过 Canvas 转换(注意跨域限制)
function imageToBase64(url, callback) {
  const img = new Image();
  img.crossOrigin = 'Anonymous'; // 需要服务器支持 CORS

  img.onload = function() {
    const canvas = document.createElement('canvas');
    canvas.width = img.width;
    canvas.height = img.height;

    const ctx = canvas.getContext('2d');
    ctx.drawImage(img, 0, 0);

    const dataURL = canvas.toDataURL('image/jpeg');
    callback(dataURL);
  };

  img.onerror = function() {
    console.error('图片加载失败');
  };

  img.src = url;
}

6. 使用 Service Worker 拦截请求

// service-worker.js
self.addEventListener('fetch', event => {
  if (event.request.url.includes('external-image')) {
    const newRequest = new Request(event.request, {
      headers: {
        ...event.request.headers,
        'Referer': null // 移除或修改 Referer
      }
    });
    event.respondWith(fetch(newRequest));
  }
});

7. 综合解决方案示例

class ImageProxy {
  constructor(options = {}) {
    this.proxyUrl = options.proxyUrl || '';
    this.useProxy = options.useProxy || false;
  }

  async loadImage(src) {
    // 方法1:尝试直接加载(无referrer)
    try {
      const img1 = new Image();
      img1.referrerPolicy = 'no-referrer';
      img1.src = src;

      await new Promise((resolve, reject) => {
        img1.onload = resolve;
        img1.onerror = reject;
      });
      return img1.src;
    } catch (e) {
      console.log('方法1失败,尝试代理...');
    }

    // 方法2:使用代理
    if (this.useProxy && this.proxyUrl) {
      const proxySrc = this.proxyUrl + encodeURIComponent(src);
      const img2 = new Image();
      img2.src = proxySrc;

      return new Promise((resolve, reject) => {
        img2.onload = () => resolve(proxySrc);
        img2.onerror = reject;
      });
    }

    // 方法3:使用 fetch
    try {
      const response = await fetch(src, {
        mode: 'cors',
        credentials: 'omit',
        headers: { 'Referer': '' }
      });
      const blob = await response.blob();
      return URL.createObjectURL(blob);
    } catch (error) {
      console.error('所有方法都失败了');
      throw error;
    }
  }
}

// 使用
const proxy = new ImageProxy({
  proxyUrl: 'https://api.codetabs.com/v1/proxy?quest=',
  useProxy: true
});

proxy.loadImage('https://external.com/image.jpg')
  .then(url => {
    document.getElementById('img').src = url;
  });

注意事项:

合法性:确保你有权访问和显示这些图片 性能:代理会增加延迟,考虑缓存策略 服务稳定性:第三方代理服务可能不稳定 CORS 限制:某些方法需要目标服务器支持 CORS 隐私考虑:修改 Referer 可能影响用户隐私跟踪

最佳实践建议:

  • 优先与图片提供方沟通,获取合法访问权限
  • 对于自己的应用,配置合适的 Referrer-Policy
  • 使用 CDN 或自建代理服务以获得更好的控制和稳定性
  • 实现优雅降级,当图片无法加载时显示占位符