WishMeLz

生活其实很有趣

处理后端返回的文件流拿到对应的文件名

/**
 * 从 HTTP 响应的 Content-Disposition 头部提取文件名
 * @param disposition Content-Disposition 头部值
 * @param keepExtension 是否保留文件扩展名,默认为 false
 * @returns 处理后的文件名
 */
export function getResBlobFileName(disposition: string | null | undefined, keepExtension = false): string {
  // 如果没有有效的 disposition 或不包含 attachment,返回时间戳作为文件名
  if (!disposition || disposition.indexOf("attachment") === -1) {
    return Date.now().toString();
  }

  // 使用正则表达式提取文件名
  const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
  const matches = filenameRegex.exec(disposition);
  let filename = matches?.[1] ?? "file";

  // 处理文件名
  filename = filename.startsWith("utf-8''") ? filename.substring(7) : filename;

  if (filename.charAt(0) === '"' && filename.charAt(filename.length - 1) === '"') {
    filename = filename.substring(1, filename.length - 1);
  }

  try {
    filename = decodeURIComponent(filename);
  } catch (error) {
    console.warn("Failed to decode filename:", error);
    // 解码失败时保持原样
  }

  if (!keepExtension) {
    const lastDotIndex = filename.lastIndexOf('.');
    if (lastDotIndex !== -1) {
      filename = filename.substring(0, lastDotIndex);
    }
  }

  return filename;
}