JS文件上传的完整指南(前端文件上传的多种方案详解)

文件上传是网站或应用程序的常见功能之一。JS文件上传成为许多开发人员首选的方式之一,因为它在不刷新页面的情况下允许用户上传文件,提高了用户友好性和良好的用户体验。但是,JS文件上传并不是一项容易完成的任务。在接下来的文章中,我们将探讨JS文件上传的多个方面。

一、上传方式

很多人都知道最基本的文件上传方法:一个包含文件上传表单的HTML页面和一个服务器端的文件接收程序。然而,如何将这个上传过程包含在前端Javascript中是值得关注的一个问题,常见的有三种方式:

1. form 表单提交方式


const formElement = document.getElementsByTagName('form')[0];
formElement.addEventListener('submit', (event) => {
    event.preventDefault();
    const formData = new FormData(formElement);
    fetch('/api/upload', {method: 'POST', body: formData})
    .then(response => {
        console.log(response);
    });
});

这里的代码中,我们通过构造 FormData 对象收集表单中的文件和字段,使用 fetch API 向服务器端发送一个 POST 请求,以触发上传操作。这种方式通常很适用于直接上传文件的场景。

2. Ajax 操作方式


const inputElement = document.getElementsByTagName('input')[0];
inputElement.addEventListener('change', (event) => {
    const file = event.target.files[0];
    const xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            console.log(xhr.response);
        }
    }
    xhr.open('POST', '/api/upload', true);
    xhr.send(file);
});

通过监听 <input> 表单元素的 change 事件,使用 XMLHttpRequest 组件上传文件,这是一种能够对上传过程进行更好地控制的方式。这种方式通常适用于需要对上传进度进行监控和整体处理的场景。

3. 使用第三方库方式


import { upload } from 'fileuploader';
const inputElement = document.getElementsByTagName('input')[0];
inputElement.addEventListener('change', (event) => {
    const file = event.target.files[0];
    upload('/api/upload', file).then(response => {
        console.log(response);
    });
});

这里我们使用了第三方类库,可以更方便地实现上传操作,并且可以通过声明式的方式来实现上传组件,从而在全局范围内使用。这种方式通常适用于复杂的上传要求和 UI 呈现。

二、文件类型限制

在一般情况下,应该对于文件的类型进行限制,以保证文件被正确地上传。现在的一些浏览器已经支持了原生的文件类型验证,但是在旧版本的浏览器上这个特性可能不存在。下面的代码为大家展示了如何进行文件类型限制:


const inputElement = document.getElementsByTagName('input')[0];
inputElement.addEventListener('change', (event) => {
    const allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
    const file = event.target.files[0];
    if (!allowedTypes.includes(file.type)) {
        alert('仅支持 jpeg, png 和 gif 文件!');
        return;
    }
    // 发送上传请求...
});

上述代码可以通过检查文件类型并仅上传符合特定类型的文件来减轻服务器 API 的负荷。

三、进度条

如果处理大文件,上传可能会需要一些时间。当用户等待时,您可以为他提供一个具有进度的实时反馈。下面展示了如何利用 AJAX 实现此功能:


const inputElement = document.getElementsByTagName('input')[0];
const progressBar = document.querySelector('.progress-bar');
inputElement.addEventListener('change', (event) => {
    const xhr = new XMLHttpRequest();
    xhr.upload.addEventListener('progress', (event) => {
        if (event.lengthComputable) {
            const percentComplete = event.loaded / event.total;
            progressBar.style.width = `${percentComplete * 100}%`;
        }
    });
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            console.log(xhr.response);
        }
    }
    xhr.open('POST', '/api/upload', true);
    xhr.send(event.target.files[0]);
});

在这个例子中,我们使用了 XMLHttpRequest 对象并监听了它的 onloadstart、onload、onprogress 及 onerror 事件。每当传输进展时,我们都将进度条的大小计算为上传的大小与总大小的比率,并就此进行更新。

四、断点续传

当上传过程失败或因某种原因被中断时,上传可能需要重新启动。要处理此类情况,您需要一些特殊的逻辑,能够检测上传的状态,并可使用户从失败点重新启动上传。这通常称之为断点续传。


function sendRequest(file) {
    const xhr = new XMLHttpRequest();
    xhr.upload.addEventListener('progress', (event) => {
        if (event.lengthComputable) {
            const percentComplete = event.loaded / event.total;
            progressBar.style.width = `${percentComplete * 100}%`;
        }
    });
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            console.log(xhr.response);
        }
    }
    xhr.open('POST', '/api/upload', true);
    xhr.setRequestHeader('Content-type', 'application/octet-stream');
    xhr.send(file.slice(start, end));
}

function startUpload(file) {
    const chunkSize = 1024 * 1024; // 1 MB
    let i = 0;
    progressBar.style.width = `0%`;
    while (i  {
    startUpload(event.target.files[0]);
});

在这个例子中,我们通过计算分块大小来进行断点续传,并在每个分块上传完成后监听 ajax 的状态。如果请求失败,可以将上传状态保存到本地,以便在以后再次继续上传。

五、总结

在这篇文章中,我们探讨了如何使用不同的方式进行 JS 文件上传,包括 form,Ajax 和第三方库。我们还学习了如何实现文件类型检查,进度条和断点续传。我们希望这篇文章能够帮助您了解 JS 文件上传的所有方面,开始在您的应用程序中使用这种功能。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平