如何区分返回内容是文件流还是json数据?

334 阅读3分钟

在前端开发中,处理不同类型的响应数据是一个常见的需求。特别是在与后端进行交互时,我们需要准确区分返回的内容是文件流(如图片、PDF等二进制文件)还是 JSON 数据。以下是一些有效的方法和技巧来进行区分。

1. 检查响应头

HTTP 响应头中包含了关于返回数据类型的重要信息。通过检查 Content-Type 头部,可以初步判断返回的内容类型。

JSON 数据

对于 JSON 响应,通常 Content-Type 会是:

  • application/json
  • text/json

示例代码:

fetch('/api/data')
  .then(response => {
    if (response.headers.get('Content-Type').includes('application/json')) {
      return response.json(); // 解析为 JSON 数据
    } else {
      throw new Error('返回的数据不是 JSON 格式');
    }
  })
  .then(data => console.log(data))
  .catch(error => console.error(error));

文件流

对于文件流,常见的 Content-Type 包括:

  • application/pdf(PDF 文件)
  • image/png(PNG 图片)
  • application/octet-stream(通用二进制流)

示例代码:

fetch('/api/download')
  .then(response => {
    const contentType = response.headers.get('Content-Type');
    if (contentType.includes('application/octet-stream') || contentType.includes('image/') || contentType.includes('application/pdf')) {
      return response.blob(); // 处理为 Blob 数据
    } else {
      throw new Error('返回的数据不是文件流');
    }
  })
  .then(blob => {
    const url = URL.createObjectURL(blob);
    // 这里可以利用 url 来下载文件或展示图片等
    console.log(url);
  })
  .catch(error => console.error(error));

2. 检查响应体内容

在某些情况下,仅通过 Content-Type 可能不足以做出准确判断。这时可以结合响应体的内容进行进一步的确认。

JSON 数据

通常 JSON 数据是以对象的形式返回的,可以通过解析尝试来判断是否为 JSON 格式:

fetch('/api/data')
  .then(response => response.text()) // 先获取文本
  .then(text => {
    try {
      const jsonData = JSON.parse(text); // 尝试解析 JSON
      console.log(jsonData); // 如果成功,说明是 JSON 数据
    } catch (error) {
      console.error('不是有效的 JSON 数据');
    }
  });

文件流

对于文件流,通常返回的数据是二进制格式,解析成字符串时可能会出现乱码,因此如果尝试将其解析为 JSON 时失败,且内容不符合 JSON 格式,则可以判断为文件流。

fetch('/api/download')
  .then(response => response.blob())
  .then(blob => {
    const reader = new FileReader();
    reader.onload = function() {
      const result = reader.result;
      // 尝试解析成 JSON,如果失败,则是文件流
      try {
        const jsonData = JSON.parse(result);
      } catch (error) {
        console.log('返回的是文件流');
      }
    };
    reader.readAsText(blob); // 读取为文本
  });

3. 使用 Fetch API 的 Response 对象

Fetch API 提供了一些方法来处理响应。我们可以利用这些方法来处理不同的响应类型。

处理 JSON 和 Blob

fetch('/api/data-or-file')
  .then(response => {
    if (response.ok) {
      // 根据 Content-Type 判断
      const contentType = response.headers.get('Content-Type');
      if (contentType.includes('application/json')) {
        return response.json(); // 处理 JSON
      } else {
        return response.blob(); // 处理 Blob
      }
    } else {
      throw new Error('网络错误');
    }
  })
  .then(data => {
    if (data instanceof Blob) {
      // 处理 Blob 数据
      console.log('这是文件流');
    } else {
      // 处理 JSON 数据
      console.log('这是 JSON 数据', data);
    }
  })
  .catch(error => console.error(error));

4. 小结

区分返回内容是文件流还是 JSON 数据的关键在于检查响应头的 Content-Type,并结合响应体内容的解析。通过使用 Fetch API 提供的方法,我们可以较为轻松地处理不同类型的响应数据。

在实际开发中,确保后端接口设计良好,返回的 Content-Type 能够准确反映数据类型,将大大简化前端的判断逻辑。