返回

前端文件上传与下载教程——助力Web开发锦上添花

前端

前言

前端文件上传和下载是Web开发中必不可少的功能,能够让用户轻松地将文件上传到服务器或从服务器下载文件。通过文件上传,用户可以提交各种类型的文件,例如图片、视频、文档等;通过文件下载,用户可以获取服务器上的文件并保存到本地。

前端文件上传

原生input控件上传

最简单的前端文件上传方式就是使用原生input控件。HTML中,我们可以使用<input>元素来创建文件上传控件。<input>元素的type属性设置为"file",允许用户选择要上传的文件。

<input type="file" name="file" multiple>

通过<input>元素,我们可以实现单个文件上传或多个文件上传。当用户选择文件后,可以在<input>元素的files属性中获取到所选文件的信息。

const input = document.querySelector('input[type="file"]');

input.addEventListener('change', (event) => {
  const files = event.target.files;

  for (const file of files) {
    console.log(file.name);
    console.log(file.size);
    console.log(file.type);
  }
});

拖拽上传

除了使用原生input控件,我们还可以实现拖拽上传功能。通过拖拽上传,用户可以将文件直接拖拽到指定区域,然后自动上传到服务器。

<div id="drop-zone">
  <p>Drop files here to upload</p>
</div>
const dropZone = document.getElementById('drop-zone');

dropZone.addEventListener('dragover', (event) => {
  event.preventDefault();
  event.stopPropagation();
  dropZone.classList.add('active');
});

dropZone.addEventListener('dragleave', (event) => {
  event.preventDefault();
  event.stopPropagation();
  dropZone.classList.remove('active');
});

dropZone.addEventListener('drop', (event) => {
  event.preventDefault();
  event.stopPropagation();
  dropZone.classList.remove('active');

  const files = event.dataTransfer.files;

  for (const file of files) {
    console.log(file.name);
    console.log(file.size);
    console.log(file.type);
  }
});

前端文件下载

前端文件下载的操作相对简单,可以使用<a>元素或JavaScript中的window.location.href方法实现。

使用<a>元素下载

<a href="file.txt" download>Download File</a>

通过<a>元素的href属性指定要下载的文件路径,并在download属性中指定下载的文件名。当用户点击<a>元素时,浏览器将自动下载该文件。

使用window.location.href方法下载

window.location.href = 'file.txt';

通过window.location.href方法也可以实现文件下载。只需将要下载的文件路径作为参数传递给该方法即可。

大文件上传处理

对于大文件上传,我们需要使用一些特殊的技巧来避免浏览器内存溢出或超时等问题。

分片上传

分片上传是指将大文件分割成多个较小的分片,然后逐个上传到服务器。分片上传可以减轻浏览器内存的压力,并避免超时问题。

const file = new File(['Hello, world!'], 'hello.txt', {
  type: 'text/plain',
});

const chunkSize = 1024 * 1024; // 1MB

const chunks = [];

for (let i = 0; i < file.size; i += chunkSize) {
  const chunk = file.slice(i, i + chunkSize);
  chunks.push(chunk);
}

const uploadChunk = (chunk, index) => {
  const formData = new FormData();
  formData.append('file', chunk);
  formData.append('index', index);

  const xhr = new XMLHttpRequest();
  xhr.open('POST', '/upload');
  xhr.send(formData);
};

for (let i = 0; i < chunks.length; i++) {
  uploadChunk(chunks[i], i);
}

断点续传

断点续传是指当文件上传中断时,可以从中断点继续上传,而不必重新上传整个文件。断点续传可以避免因网络中断或服务器故障导致的文件上传失败。

const file = new File(['Hello, world!'], 'hello.txt', {
  type: 'text/plain',
});

const chunkSize = 1024 * 1024; // 1MB

const chunks = [];

for (let i = 0; i < file.size; i += chunkSize) {
  const chunk = file.slice(i, i + chunkSize);
  chunks.push(chunk);
}

const uploadChunk = (chunk, index) => {
  const formData = new FormData();
  formData.append('file', chunk);
  formData.append('index', index);

  const xhr = new XMLHttpRequest();
  xhr.open('POST', '/upload');
  xhr.setRequestHeader('Content-Range', `bytes ${index * chunkSize}-${(index + 1) * chunkSize - 1}/${file.size}`);

  xhr.onload = () => {
    if (xhr.status === 200) {
      // 上传成功,继续上传下一个分片
      if (index < chunks.length - 1) {
        uploadChunk(chunks[index + 1], index + 1);
      }
    } else {
      // 上传失败,记录断点并稍后重试
      const breakpoint = index * chunkSize;
      localStorage.setItem('breakpoint', breakpoint);
    }
  };

  xhr.send(formData);
};

// 检查本地存储中是否有断点
const breakpoint = localStorage.getItem('breakpoint');
if (breakpoint) {
  // 从断点处继续上传
  const index = Math.floor(breakpoint / chunkSize);
  uploadChunk(chunks[index], index);
} else {
  // 从头开始上传
  uploadChunk(chunks[0], 0);
}

结语

前端文件上传和下载是Web开发中的基本操作,也是非常实用的功能。通过本文的介绍,希望您能够掌握前端文件上传和下载的技巧,并将其应用到您的Web开发项目中。