iframe下载前端不能自定义文件名,需要后端处理.

    // 下载文件
    downloadFile(item) {
      const iframe = document.createElement("iframe");
      iframe.style.display = "none"; // 防止影响页面
      iframe.style.height = 0; // 防止影响页面
      iframe.src = item.url; 
      document.body.appendChild(iframe); // 这一行必须,iframe挂在到dom树上才会发请求
      // 5分钟之后删除(onload方法对于下载链接不起作用,就先抠脚一下吧)
      setTimeout(()=>{
        iframe.remove();
      }, 5 * 60 * 1000);
    }

当时使用的这个方案下载文件,后端使用的是阿里云的oss对象存储,然后下载MP4文件的时候一直打开预览,不会触发浏览器下载行为.后面查看阿里云文档,可以设置文件的响应头或者,在请求url后面拼接

'?response-content-type=application/octet-stream';

例子:

/**
 * 下载文件
 * @param link 文件下载地址
 */
export const download = links => {
    const iframe = document.createElement("iframe");
    iframe.style.display = "none"; // 防止影响页面
    iframe.style.height = 0; // 防止影响页面
    iframe.src = links+'?response-content-type=application/octet-stream';
    document.body.appendChild(iframe); // 这一行必须,iframe挂在到dom树上才会发请求
    // 30s之后删除
    setTimeout(() => {
        iframe.remove();
    }, 30000);
};

a标签下载,支持前端自定义文件名,blob要带上 responseType: 'blob'
常见下载功能

download(downloadUrl, data = {}, fileName = '下载.xlsx') {
      const option = {
        responseType: 'blob',
      };
      Axios.post(downloadUrl, data, option).then((res) => {
        const { data: bData } = res;
        const blob = new Blob([bData], { type: 'application/zip' });
        if ('download' in document.createElement('a')) {
          // 非IE下载
          const elink = document.createElement('a');
          elink.download = fileName;
          elink.style.display = 'none';
          elink.href = URL.createObjectURL(blob);
          document.body.appendChild(elink);
          elink.click();
          URL.revokeObjectURL(elink.href); // 释放URL 对象
          document.body.removeChild(elink);
        } else {
          // IE10+下载
          navigator.msSaveBlob(blob, fileName);
        }
      });
    },

下载2-优化

export const downloadFile = (downloadUrl, data, fileName = '导出列表.xlsx', type = 'application/octet-stream') => {
  const option = {
    responseType: 'blob',
  }
  return Axios.post(downloadUrl, data, option).then((res) => {
    const { data: bData } = res;
    const blob = new Blob([bData], {type});
    // 正常情况下blob.type为空,因为返回的是文件流,而返回json就说明报错了
    if (blob.type === 'application/json') {
      const reader = new FileReader();
      reader.onload = function () {
        const content = reader.result;
        const { msg } = JSON.parse(content); // 错误信息
        Message.error(msg);
      };
      reader.readAsText(bData);
      return;
    }

    if ('download' in document.createElement('a')) { // 非IE下载
      const elink = document.createElement('a');
      elink.download = fileName;
      elink.style.display = 'none';
      elink.href = URL.createObjectURL(blob);
      document.body.appendChild(elink);
      elink.click();
      URL.revokeObjectURL(elink.href); // 释放URL 对象
      document.body.removeChild(elink);
    } else { // IE10+下载
      navigator.msSaveBlob(blob, fileName);
    }
  })
};

下载3get

    downloadGet(downloadUrl, params = {}, fileName = '模板.xls') {
      const loading = this.$loading({
        lock: true,
        text: '请稍候',
        background: 'rgba(0, 0, 0, 0)'
      });
      const option = {
        responseType: 'blob',
      };
      Axios.get(downloadUrl, {params, ...option}).then((res) => {
        loading.close();
        if(res.data&&res.data.type=='application/json') {
          this.$message({
            type: 'error',
            message: '导出出错!'
          });
          return;
        }
        const blob = new Blob([res.data], { type: "application/zip" });
        if ('download' in document.createElement('a')) {
          // 非IE下载
          const elink = document.createElement('a');
          elink.download = fileName;
          elink.style.display = 'none';
          elink.href = URL.createObjectURL(blob);
          document.body.appendChild(elink);
          elink.click();
          URL.revokeObjectURL(elink.href); // 释放URL 对象
          document.body.removeChild(elink);
        } else {
          // IE10+下载
          navigator.msSaveBlob(blob, fileName);
        }
      }).catch(() => {
        loading.close();
      });
    }

常见下载方式

this.axios({
  url: baseUrl + '/mails/downloadZipFile',
  method: 'GET',
  responseType: 'arraybuffer',
  params: {
    strMailId: this.parm['strMailId']
  }
}).then((res) => {
  const content = res.data
  const blob = new Blob([content], {type: "application/zip"})
  var timestamp = (new Date()).valueOf();
  const fileName = timestamp + '.zip'
  if ('download' in document.createElement('a')) { // 非IE下载
    const elink = document.createElement('a')
    elink.download = fileName
    elink.style.display = 'none'
    elink.href = window.URL.createObjectURL(blob)
    document.body.appendChild(elink)
    elink.click()
    window.URL.revokeObjectURL(elink.href) // 释放URL 对象
    document.body.removeChild(elink)
  } else { // IE10+下载
    navigator.msSaveBlob(blob, fileName)
  }
}).catch((err) => {
  console.log(err);
})

vue3

import type { AxiosResponse } from 'axios'
import { replace } from 'lodash'

const getFileNameFromContentDisposition = (text?: string, defaultFilename?: string) => {
  const defaultFileName = defaultFilename || '下载文件.csv'
  if (!text) {
    return defaultFileName
  }
  const strArr = text.split(';')
  for (let index = 0; index < strArr.length; index++) {
    const element = strArr[index]
    if (element.trim().startsWith('filename')) {
      const name = element.substring(element.indexOf('=') + 1).trim()
      const nameR = replace(name, /\"/, '')
      return decodeURIComponent(nameR)
    }
  }
  return defaultFileName
}

export function exportBlobFile(res: AxiosResponse, type = 'application/vnd.ms-excel', defaultFilename?: string) {
  try {
    const fileType = res.headers['content-type'] || type
    const fileContent = res.data
    const fileName = getFileNameFromContentDisposition(res.headers['content-disposition'], defaultFilename)
    let blob = new Blob([fileContent], { type: fileType }) // 默认excel
    let filename = fileContent.filename || fileName
    let URL = window.URL || window.webkitURL
    let objectUrl = URL.createObjectURL(blob)
    let a = document.createElement('a')
    a.href = objectUrl
    a.download = filename
    document.body.appendChild(a)
    a.click()
    a.remove()
  } catch (error) {
    console.error('下载失败', error)
  }
}

已有 2 条评论

  1. 哥哥好大我好喜欢

    1. @何胡锐

      有你一半大吗??

发表评论