js原生实现img和pdf添加请求头完成预览,理论上适合所有框架

32 阅读1分钟

HTML 原生标签(如 <img src="...">)发起的请求是由浏览器自动处理的,开发者无法干预其请求头。这是出于安全和简洁性的设计考量。因此,若服务器要求特定请求头(如 JWT Token),直接使用 <img> 将导致 401/403 错误。

PDF 文件通常通过 <iframe> 渲染。与图片类似,这些标签也无法携带请求头。我们可以用相同思路:先获取 PDF 的二进制流,再生成可嵌入的 URL。

实现步骤

图片
  1. 使用 fetch 请求图片资源,并在 headers 中添加认证信息;

  2. 将响应转为 Blob 对象;

  3. 通过 URL.createObjectURL(blob) 生成本地 URL;

  4. 将该 URL 赋给 <img>src 属性;

  5. 图片加载完成后,调用 URL.revokeObjectURL() 释放内存。

示例代码

不讲屁话,全是干货!Talk is cheap, show you the code !


async function loadImageWithAuth(url, token, imgElement) {

  try {

    const res = await fetch(url, {

      headers: {

        Authorization: 'Bearer ' + token

      }

    });

  


    if (!res.ok) throw new Error('Failed to load image');

  


    const blob = await res.blob();

    const objectUrl = URL.createObjectURL(blob);

  


    imgElement.src = objectUrl;

  


    // 清理内存:图片加载完成后释放 Blob URL

    imgElement.onload = () => {

      URL.revokeObjectURL(objectUrl);

    };

  } catch (error) {

    console.error('Error loading image:', error);

    imgElement.src = ''; // 可选:显示占位图或错误提示

  }

}

  


// 使用示例

const img = document.getElementById('protected-image');

loadImageWithAuth('https://api.example.com/image.jpg', 'your-jwt-token', img);


PDF
  1. fetch 获取 PDF 资源(带 Authorization 头);

  2. 读取 response.bodyReadableStream

  3. 将流数据分块收集并合并为 Blob

  4. 创建 Blob URL 并赋给 <iframe>src

示例代码

不讲屁话,全是干货!Talk is cheap, show you the code !


async function loadPdfWithAuth(url, token, iframeElement) {

  try {

    const res = await fetch(url, {

      headers: {

        Authorization: 'Bearer ' + token

      }

    });

  


    if (!res.ok) throw new Error('Failed to load PDF');

  


    const reader = res.body.getReader();

    const chunks = [];

  


    while (true) {

      const { done, value } = await reader.read();

      if (done) break;

      chunks.push(value);

    }

  


    const blob = new Blob(chunks, { type: 'application/pdf' });

    const objectUrl = URL.createObjectURL(blob);

  


    iframeElement.src = objectUrl;

  


    // 清理内存

    iframeElement.onload = () => {

      URL.revokeObjectURL(objectUrl);

    };

  } catch (error) {

    console.error('Error loading PDF:', error);

    iframeElement.src = ''; // 或跳转到错误页面

  }

}

  


// 使用示例

const pdfIframe = document.getElementById('pdf-preview');

loadPdfWithAuth('https://api.example.com/report.pdf', 'your-jwt-token', pdfIframe);


原文链接:xuehuayu.cn/article/de2…