前端文件下载方法(包含get和post)

export const downloadFileWithIframe = (url, name) => {
  const iframe = document.createElement('iframe');
  iframe.style.display = 'none'; // 防止影响页面
  iframe.style.height = 0; // 防止影响页面
  iframe.name = name;
  iframe.src = url;

  document.body.appendChild(iframe); // 这一行必须,iframe挂在到dom树上才会发请求
  // 5分钟之后删除(onload方法对于下载链接不起作用,就先抠脚一下吧)
  setTimeout(() => {
    iframe.remove();
  }, 5 * 60 * 1000);
  // console.log(url)
//   window.open(url)
};

export const downloadFileWithWindow = (url, name) => {
  const otherWindow = window.open(url, name);
  otherWindow.opener = null;
};

/**
 * @param { object } data 参数
 * @param { string } url 路径
 * @description 处理下载方法
 */
export function handleWindowDownload(url, data, name) {
  if (!url) return;
  let paramStr = '';
  if (data && typeof data === 'object') {
    const keys = Object.keys(data);
    const arr = [];
    if (keys.length > 0) {
      keys.forEach(item => {
        arr.push(`${item}=${data[item]}`);
      });
    }
    paramStr = arr.join('&');
  }
  url += paramStr ? `?${paramStr}` : '';

  downloadFileWithWindow(`${url}`, name);
}

// url 为请求地址,name 为form表单的target 的name 可以随意写 data1为需要请求的数据
export function openPostWindow(url, name, data1) {
  // 创建form表单,以下数form表单的各种参数
 
  var tempForm = document.createElement('form');
  tempForm.id = 'tempForm1';
  tempForm.method = 'post';
  tempForm.action = url;
  tempForm.target = name;
  // 创建标签 <input></input> 标签 然后设定属性,最后追加为 form标签的子标签
  var hideInput1 = document.createElement('input');
  hideInput1.type = 'hidden';
  hideInput1.name = 'data';
  hideInput1.value = data1;
  tempForm.appendChild(hideInput1);

  if (document.all) {
    // IE
    tempForm.attachEvent('onsubmit', function() {});
  } else {
    // firefox
    tempForm.addEventListener('submit', function() {}, false);
  }
  document.body.appendChild(tempForm);
  if (document.all) {
    tempForm.fireEvent('onsubmit');
  } else {
    tempForm.dispatchEvent(new Event('submit'));
  }
  // 提交POST请求
  tempForm.submit();
  // 删除整个form标签
  document.body.removeChild(tempForm);
}
  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前端程序: ``` // HTML代码 <!DOCTYPE html> <html> <head> <title>大文件分片下载</title> </head> <body> <h1>大文件分片下载</h1> <form> <label for="fileUrl">文件地址:</label> <input type="text" id="fileUrl" name="fileUrl"><br> <label for="chunkSize">分片大小:</label> <input type="number" id="chunkSize" name="chunkSize"><br> <button type="button" onclick="startDownload()">开始下载</button> </form> <div id="progress"></div> <script> function startDownload() { let fileUrl = document.getElementById("fileUrl").value; let chunkSize = document.getElementById("chunkSize").value; let xhr = new XMLHttpRequest(); xhr.open("POST", "/download"); xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { document.getElementById("progress").innerHTML = xhr.responseText; } }; xhr.send(JSON.stringify({fileUrl: fileUrl, chunkSize: chunkSize})); } </script> </body> </html> ``` 后端程序: ``` // Node.js代码 const express = require("express"); const axios = require("axios"); const fs = require("fs"); const app = express(); app.use(express.json()); app.post("/download", (req, res) => { let fileUrl = req.body.fileUrl; let chunkSize = parseInt(req.body.chunkSize); let fileName = fileUrl.split("/").pop(); let fileSize = 0; let chunks = []; let downloaded = 0; let startTime = new Date().getTime(); let endTime; axios.head(fileUrl).then(response => { fileSize = parseInt(response.headers["content-length"]); let numChunks = Math.ceil(fileSize / chunkSize); for (let i = 0; i < numChunks; i++) { chunks.push({start: i * chunkSize, end: (i + 1) * chunkSize - 1}); } return Promise.all(chunks.map(chunk => { let headers = {"Range": `bytes=${chunk.start}-${chunk.end}`}; return axios.get(fileUrl, {headers: headers, responseType: "arraybuffer"}); })); }).then(responses => { let buffer = Buffer.concat(responses.map(response => Buffer.from(response.data))); fs.writeFile(fileName, buffer, err => { if (err) throw err; endTime = new Date().getTime(); let elapsedTime = (endTime - startTime) / 1000; let downloadSpeed = fileSize / elapsedTime / 1024 / 1024; res.send(`下载完成,用时${elapsedTime.toFixed(2)}秒,平均下载速度${downloadSpeed.toFixed(2)}MB/s。`); }); }).catch(error => { console.log(error); res.sendStatus(500); }); }); app.listen(3000, () => console.log("服务器已启动。")); ``` 说明: 1. 前端程序使用了HTML、CSS、JavaScript技术,提供了一个表单,用户可以输入文件地址和分片大小,然后点击“开始下载”按钮来触发下载操作。表单会通过Ajax技术向后端程序发送一个POST请求,请求体是一个JSON对象,包含文件地址和分片大小两个属性。 2. 后端程序使用了Node.js、Express、Axios、fs等技术,接收到前端程序发送的POST请求后,首先发送一个HEAD请求获取文件大小,然后根据分片大小将文件分成多个片段,然后使用Promise.all并行地发送多个GET请求下载每个片段,最后将所有片段拼接起来,保存到本地文件中。下载结束后,计算下载用时和平均下载速度,并将结果通过HTTP响应发送回前端程序。 3. 这个程序可以实现大文件分片下载,可以提高下载速度和下载成功率,因为即使某个片段下载失败,其他片段仍然可以继续下载,最终将所有片段拼接起来即可得到完整的文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值