场景题:大文件上传 ?| 过总字节一面😱

前言

刚刚要吃饭,放下书包 , 适才掏出手机点开支付码 , 微信嘀嘟一声 , 划过一条消息 :过佬 发来一张图片 , 我好奇地点开群聊消息 , 点入图片 , 不禁一惊 , 过佬出征字节了😱 , 面经如下 :

现在都流行问场景题呢👈 , 之前在掘金上看到个观点 : 在 AI 大行其道 の 今天 , 八股一问便有答案 , 也是说在一定程度上打破了信息差 ; 未来在传统八股方面会减弱 , 将会聚焦与场景化 , 各位掘友怎被看 ?

哈哈 , 不管怎么样😏 , 如果八股背成了八股 , 自然无用 , 利用八股解决实际问题 ,有何尝不是场景化地具体实现呢 ?

今天 , 开始一起研究下大文件上传吧 ~

我之前写过一篇文章关于大文件上传 , 主要是用于实践 , 很多细节没有挖掘哈~

大文件上传👈 | React + NestJs |分片、断点续传、秒传🚀 , 你是否知道 ???

现在进行深入拷打 ~

就是因为这篇文章 , 我也被拷打过😭 , 面经如下 :

完整的面试经过可以查看我之前写的一篇面经:

2025年2月凉面与热面(1)------杭州AI公司一二面

过总

先看过佬的面经

问题一 : 大文件上传以及应用场景优化

这个是十分大的问题 , 拆解下来就是应用场景性能优化 , 可以先泛泛谈之 ~

应用场景

这边举一些例子:

  • 云存储:用户向百度网盘、阿里云盘等上传大型视频、软件安装包等,利用大文件上传功能,即便网络不稳定也能成功上传。
  • 企业办公:设计师上传大型设计素材文件到公司共享服务器,或程序员上传项目部署包等。
  • 在线视频制作:创作者将本地高清视频素材上传到在线剪辑平台。

在这些例子里面 , 我有个点有深刻影响 🤡👈 ------ 程序员上传项目部署包 , 我之前文章提到 (本地构建/手动上传/服务器运行) 的部署方案 , 在这个过程中 , 我就需要在本地打包上传服务器 , 这就是大文件上传 ~

我的远程实习(四)| Ailln叫我docker部署项目,我顺便填了以前的坑

性能优化

  • 网络层面:利用 CDN(内容分发网络),将文件切片缓存到离用户近的节点,加快传输速度。如腾讯云 CDN 可加速文件上传(旨在通过将网站内容缓存到全球各地的节点,实现快速、稳定和高效的访问体验)
  • 前端优化:使用多线程或 Web Workers 实现多切片并发上传。像 JavaScript 借助 Web Workers 可开启多个线程同时上传不同切片。
  • 后端优化:优化服务器存储和文件合并逻辑,采用分布式存储系统,如 Ceph,提升存储和处理能力。

问题二:断点续传,怎么确认上传完了

断点续传原理 :在上传过程中记录已上传切片信息,网络中断恢复后,从上次中断处继续上传。例如,上传 100 个切片的文件,传到第 30 个时断网,恢复后从第 31 个开始。
确认上传完成方式

  • 计数确认:前端记录已上传切片数量,后端接收切片时也记录。当两端记录的已上传切片数都等于总分片数,确认上传完成。比如前端记录上传了 100 个切片中的 100 个,后端也接收了 100 个,即上传完毕。
  • 哈希校验:对完整文件计算哈希值(如 MD5、SHA - 1 等),上传过程中服务器对合并后的文件计算哈希值,两者相等则确认上传完成。例如上传一个软件安装包,本地计算其 MD5 值,服务器合并后计算 MD5 值与之比对。

问题三:用户上传到一半,重新刷新页面,要不要重新上传

不需要重新上传的情况 :若前端和后端有完善的断点续传机制,且能记录已上传切片信息。比如前端使用 IndexedDB 存储已上传切片索引,后端数据库记录接收情况。刷新页面后,前端从** IndexedDB** 读取信息,和后端核对,接着传未上传切片。
需要重新上传的情况:如果没有有效的状态记录和断点续传机制,刷新页面后前端无法知晓已上传进度,可能会重新上传。例如简单的单线程上传脚本,没做任何状态保存,刷新后只能从头开始。

问题四:文件分片的 id 记录在哪

前端记录

  • 内存变量 :在 JavaScript 中,可定义变量存储切片 id。如let uploadedChunkIds = [];,每上传一个切片,将其 id push 进数组。适用于简单页面,页面刷新数据丢失。
  • 本地存储 :使用localStorageIndexedDB。如localStorage.setItem('chunkIds', JSON.stringify(uploadedChunkIds)); ,可长期保存,支持断点续传,适用于复杂大文件上传场景。

后端记录

  • 数据库:存入关系型数据库(如 MySQL)或非关系型数据库(如 MongoDB) 。以 MySQL 为例,建表记录文件 id、切片 id、上传状态等信息。方便服务器端管理和查询,支持多用户、大规模文件上传场景。
  • 缓存:如 Redis,可快速记录和查询切片 id 状态。适合高并发场景,能提升查询和处理速度。

以上就是过佬面经中的大文件上传了,接下来再来拷打一下 !!! 分别从不同角度拷打 , 可能答案相似之处甚多

我的

以下是对图中文件上传相关问题的详细深刻解释:

如何并发的执行文件上传

  • 原理 :利用浏览器或运行环境的多线程、异步特性,同时发起多个文件切片的上传请求。比如在前端 JavaScript 中,可将每个切片的上传任务封装成 Promise,再借助 Promise.all 等方式并发执行。
  • 实现方式 :先把大文件切片,如将一个 500MB 的文件切成 500 个 1MB 的切片。然后为每个切片创建上传任务,像使用 XMLHttpRequestFetch API 来发起请求。例如用 Fetch API 时,代码类似 fetch('/upload', { method: 'POST', body: chunk })chunk 为切片数据),最后通过 Promise.all 并发执行这些请求。
  • 注意事项:需控制并发数量,避免因过多并发请求耗尽网络资源或导致浏览器性能下降。可通过自定义队列等方式,设定最大并发数,如设置为 5,当正在执行的上传任务小于 5 时,才从任务队列中取出新切片进行上传。

一般的并发数是多少

  • 影响因素
    • 网络环境:在高速稳定的企业专线网络下,可适当提高并发数;而在普通家庭宽带或移动网络环境中,过高并发数可能导致网络拥塞,一般并发数不宜过高。
    • 服务器性能:服务器配置高、带宽充足,能承受较多并发请求;若服务器性能有限,过多并发会使其负载过高,影响服务稳定性。
    • 浏览器限制:不同浏览器对并发连接数有不同限制,比如 Chrome 浏览器对同一个域名的并发连接数一般限制在 6 - 8 个左右 。
  • 常见取值范围:通常在 3 - 10 之间。对于小型项目或对实时性要求不高的场景,3 - 5 较为合适;而在一些大型文件存储系统且网络和服务器条件较好时,可能会设置到 8 - 10 。但实际应用中需通过测试来确定最优并发数。

如果分片5片,其中两片传完了,接下来怎么办

  • 正常情况:继续按顺序或并发上传剩余的 3 片。若采用顺序上传,依次发起对剩余切片的上传请求;若采用并发上传且还有并发名额,将剩余切片的上传任务加入并发队列执行。
  • 异常处理:若在上传过程中发现已上传的两片存在问题(如通过 MD5 校验发现文件损坏 ),需重新上传这两片。同时,若上传过程中网络中断,需记录已上传切片的状态,待网络恢复后,根据记录继续上传剩余切片或重新上传有问题的切片。
  • 后端协作:后端需配合记录已成功接收的切片信息,以便前端在各种情况下能准确判断上传进度和下一步操作。比如后端可在数据库中记录每个切片的接收状态 。

文件切片大一点好,还是小一点好? 分片切多少怎么考虑

  • 切片大的优劣
    • 优点:切片数量少,上传任务调度开销小,合并操作相对简单,在网络稳定且带宽充足时,能快速完成上传。例如在企业内部高速网络环境下上传大型安装包。
    • 缺点:单个切片传输时间长,网络不稳定时,易因超时等问题导致整个切片重传,浪费时间和流量。
  • 切片小的优劣
    • 优点:单个切片传输快,网络波动影响小,便于实现断点续传,重传成本低。比如在网络状况复杂的公共 Wi - Fi 环境中上传文件。
    • 缺点:切片数量多,调度和管理开销大,后端合并操作也更复杂。
  • 考虑因素
    • 网络状况:网络稳定且带宽大,可适当增大切片;网络不稳定则宜采用较小切片。
    • 文件类型:对实时性要求高的文件(如视频流 ),小切片可减少卡顿;对完整性要求高的文件(如可执行程序 ),大切片可能更合适。
    • 服务器性能:服务器处理能力强、存储 I/O 性能高,可处理较多切片;若服务器性能有限,大切片可减轻其处理压力。

如何实现秒传?(MD5值比对)

  • 原理:利用文件内容的唯一性,通过计算文件的 MD5 值(一种哈希算法,能为文件生成唯一的固定长度字符串 )来标识文件。用户上传文件前,先计算其 MD5 值并发送给服务器,服务器在存储中查找是否有相同 MD5 值的文件。若有,直接将该文件与用户关联,实现秒传;若无,则开始正常上传流程。
  • 实现步骤
    • 前端计算:在前端使用相关库(如 js - md5 库 )计算文件的 MD5 值。
    • 服务器查找:服务器接收到 MD5 值后,在文件索引数据库中查询是否存在相同 MD5 值的文件记录。
    • 结果处理:若找到,向用户返回已存在文件的信息,完成秒传;若未找到,通知前端开始上传文件切片,并在上传完成后将新文件及其 MD5 值记录到数据库。
  • 安全性和局限性:MD5 算法存在碰撞概率(不同文件可能有相同 MD5 值 ),但概率极低。在实际应用中,可结合其他校验方式(如文件大小、文件头信息等 )提高准确性。

前端如何实现并发上传的 ?

大文件并发上传通常按以下步骤和方式实现:

1. 文件切片

先把大文件分割成若干较小的数据块,比如将一个 100MB 的文件按 1MB 大小切成 100 个切片。在前端,利用 JavaScript 的 Blob.prototype.slice 方法就能实现,示例代码如下:

javascript 复制代码
function splitFile(file, chunkSize = 5 * 1024 * 1024) {
    const chunks = [];
    let start = 0;
    while (start < file.size) {
        const chunk = file.slice(start, start + chunkSize);
        chunks.push(chunk);
        start += chunkSize;
    }
    return chunks;
}

2. 并发控制策略

  • 基于 Promise.all 并发 :将每个切片的上传请求封装成 Promise 对象,存进数组,再用 Promise.all 并发执行这些 Promise。举例:
javascript 复制代码
const chunks = splitFile(file);
const promises = chunks.map((chunk, index) => {
    const formData = new FormData();
    formData.append('chunk', chunk);
    formData.append('index', index);
    return fetch('/upload', { method: 'POST', body: formData });
});
await Promise.all(promises);

不过,这种方式可能因同时发起过多请求,耗尽系统资源或造成网络拥塞。

  • 队列控制并发数:设定最大并发数,用队列管理切片上传。比如设置最大并发数为 5,上传队列里存放待上传切片,当前上传数小于 5 且队列有切片时,就取出切片上传。示例代码:
javascript 复制代码
const MAX_CONCURRENT_UPLOADS = 5;
const uploadQueue = [];
let activeUploads = 0;

function enqueueUpload(file) {
    uploadQueue.push(file);
    processQueue();
}

function processQueue() {
    if (activeUploads < MAX_CONCURRENT_UPLOADS && uploadQueue.length > 0) {
        const file = uploadQueue.shift();
        activeUploads++;
        uploadFile(file).finally(() => {
            activeUploads--;
            processQueue();
        });
    }
}

3. 前端上传实现

  • 利用 XMLHttpRequest 或 Fetch API :通过这两个 API 发起切片上传请求。以 XMLHttpRequest 为例:
javascript 复制代码
function uploadChunk(chunk, index) {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open('POST', '/upload', true);
        xhr.onload = () => {
            if (xhr.status === 200) {
                resolve();
            } else {
                reject(new Error('Chunk upload failed'));
            }
        };
        xhr.onerror = () => {
            reject(new Error('Upload error'));
        };
        const formData = new FormData();
        formData.append('chunk', chunk);
        formData.append('index', index);
        xhr.send(formData);
    });
}

4. 后端处理

后端接收切片请求,可借助像 Express.js(Node.js)、Django(Python)等框架。以 Express.js 为例,示例代码如下:

javascript 复制代码
const express = require('express');
const multer = require('multer');
const app = express();
const upload = multer({ dest: 'uploads/' });

app.post('/upload', upload.single('chunk'), (req, res) => {
    // 处理接收到的切片,可记录切片信息到数据库等
    res.status(200).send('Chunk received successfully');
});

5. 切片合并

所有切片都上传到后端后,要按顺序合并成原始文件。比如在 Node.js 里,使用 fs.appendFileSync 方法,先创建空文件,再把切片数据依次追加进去:

javascript 复制代码
const fs = require('fs');
const path = require('path');

function mergeChunks(chunkPaths, outputPath) {
    const writeStream = fs.createWriteStream(outputPath);
    chunkPaths.forEach((chunkPath) => {
        const readStream = fs.createReadStream(chunkPath);
        readStream.pipe(writeStream, { end: false });
        readStream.on('end', () => {
            fs.unlinkSync(chunkPath); // 合并后删除临时切片文件
        });
    });
    writeStream.on('finish', () => {
        console.log('File merged successfully');
    });
}

此外,部分云存储服务(如阿里云 OSS 等)的 SDK 也提供了并发上传功能,像 Java SDK 用 taskNum 、Python SDK 用 num_threads 参数来控制并发数 ,使用时按对应 SDK 文档配置即可实现大文件并发上传。

除了采用 promise.all 并发上传 , 你还知道什么 ?

除了基于Promise.all并发外,还有以下并发控制策略:

自定义队列控制

  • 原理:维护一个任务队列和一个记录当前正在执行任务数量的变量。设定最大并发数,当有新任务时,先放入队列。若当前执行任务数小于最大并发数,从队列取出任务执行;任务完成后,减少当前执行任务数,并检查队列,若有剩余任务则继续取出执行。
  • 示例代码(JavaScript)
javascript 复制代码
class TaskQueue {
    constructor(maxConcurrent) {
        this.maxConcurrent = maxConcurrent;
        this.currentCount = 0;
        this.queue = [];
    }
    addTask(taskFn) {
        return new Promise((resolve, reject) => {
            this.queue.push({ taskFn, resolve, reject });
            this.processQueue();
        });
    }
    processQueue() {
        if (this.currentCount >= this.maxConcurrent || this.queue.length === 0) {
            return;
        }
        const { taskFn, resolve, reject } = this.queue.shift();
        this.currentCount++;
        taskFn()
          .then(resolve)
          .catch(reject)
          .finally(() => {
                this.currentCount--;
                this.processQueue();
            });
    }
}
// 使用示例
const taskQueue = new TaskQueue(3);
const tasks = Array.from({ length: 10 }, (_, i) => () => new Promise((resolve) => setTimeout(() => {
    console.log(`Task ${i} completed`);
    resolve();
}, 1000 * (i + 1))));
const executeTasks = async () => {
    const promises = tasks.map(task => taskQueue.addTask(task));
    await Promise.all(promises);
    console.log('All tasks completed');
};
executeTasks();

生成器函数结合yield

  • 原理 :利用生成器函数可以暂停和恢复执行的特性,配合yield关键字手动控制异步任务的执行顺序和并发情况。在生成器函数内部逐个生成异步任务,每次yield一个任务,等待其完成后再继续执行下一个任务。
  • 示例代码(JavaScript)
javascript 复制代码
function* taskGenerator() {
    yield new Promise((resolve) => setTimeout(() => {
        console.log('Task 1 completed');
        resolve();
    }, 1000));
    yield new Promise((resolve) => setTimeout(() => {
        console.log('Task 2 completed');
        resolve();
    }, 1500));
    yield new Promise((resolve) => setTimeout(() => {
        console.log('Task 3 completed');
        resolve();
    }, 2000));
}
const runner = async function () {
    const gen = taskGenerator();
    let result;
    do {
        result = gen.next();
        if (!result.done) {
            await result.value;
        }
    } while (!result.done);
    console.log('All tasks in generator completed');
};
runner();

消息队列

  • 原理:将异步任务放入消息队列中,由多个消费者(可以是线程、进程等)从队列中获取任务并并行处理。消息队列会按照一定规则(如先进先出)分配任务给消费者,能处理大量异步任务且允许一定延迟。适用于后端系统处理高并发任务场景,像大型电商系统处理订单、物流等任务。
  • 示例(以RabbitMQ为例,Python语言)
python 复制代码
import pika

# 连接RabbitMQ服务器
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

# 声明队列
channel.queue_declare(queue='task_queue')

# 生产者发送任务消息
for i in range(10):
    message = f"Task {i}"
    channel.basic_publish(exchange='', routing_key='task_queue', body=message)
print("Tasks sent to queue")

# 关闭连接
connection.close()

# 消费者接收并处理任务(另一个Python脚本示例)
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='task_queue')

def callback(ch, method, properties, body):
    print(f"Received and processed: {body}")

channel.basic_consume(queue='task_queue', on_message_callback=callback, auto_ack=True)
print('Waiting for tasks...')
channel.start_consuming()

限流算法

  • 令牌桶算法:系统按固定速率生成令牌放入桶中,桶有最大容量。请求到来时需从桶中获取令牌,有令牌则可继续处理,无令牌则请求被限流。比如设定桶容量为100个令牌,每秒生成10个令牌,若请求瞬间到来200个,只能处理100个,剩余100个等待新令牌生成。
  • 漏桶算法:请求像水一样注入漏桶,漏桶以固定速率流出水(处理请求),若注入速度过快,桶满后多余请求会被丢弃。可想象一个底部有小孔的桶,水不断注入但从小孔恒定流出,水注入太快就会溢出。
  • 应用场景:在高并发网络请求场景中,防止服务器因请求过多负载过高。如Web服务器对API接口请求进行限流,保护服务器稳定运行。

第三方库

  • p-limit:轻量级Promise并发控制库。可设置最大并发数,简单易用。示例代码:
javascript 复制代码
const limit = require('p-limit')(2); // 设置最大并发数为2
const tasks = [
    () => new Promise((resolve) => setTimeout(() => { console.log('Task 1'); resolve(); }, 1000)),
    () => new Promise((resolve) => setTimeout(() => { console.log('Task 2'); resolve(); }, 1500)),
    () => new Promise((resolve) => setTimeout(() => { console.log('Task 3'); resolve(); }, 2000))
];
const runTasks = async () => {
    const results = await Promise.all(tasks.map(task => limit(task)));
};
runTasks();
  • async - pool:支持多种并发策略的Promise并发控制库,能灵活控制并发任务数量、处理任务队列等 。

番外

如何在前端实现文件的断点续传,并确保大文件安全可靠上传?

回答重点

为了在前端实现文件的断点续传,并确保大文件能够安全可靠地上传,我们需要以下关键技术和步骤:

  1. 文件分块上传 (Chunked Upload) :将大文件分成多个小块,每个小块可以独立上传,这样即便在上传过程中网络中断,我们也只需要重新上传未完成的小块,而不必重新上传整个文件。
  2. 断点续传标识 (Resume Identifier) :为了实现断点续传,我们需要一个唯一的标识符来标记已经上传的分块。通常可以通过文件的名字、大小和哈希值生成这样一个标识符。
  3. MD5 校验 (MD5 Checksum) :在上传每个分块之后,计算其 MD5 校验值,并在服务器端进行校验,确保分块在传输过程中没有被篡改或损坏。
  4. 并发上传 (Concurrent Uploads) :利用浏览器的并发上传能力,可以同时上传多个分块,提高上传速度。
  5. 进度监控 (Progress Monitoring) :利用 XMLHttpRequest 或 Fetch API 的进度事件,可以实时跟踪上传进度,并在前端界面上显示。
扩展知识
  1. 文件分块实现:我们可以利用 JavaScript 的 File 对象和 Blob.prototype.slice 方法将文件分成多个小块。例如:
javascript 复制代码
const chunkSize = 5 * 1024 * 1024; // 每块5MB
const file = document.getElementById('fileInput').files[0];
const totalChunks = Math.ceil(file.size / chunkSize);

for (let i = 0; i < totalChunks; i++) {
    const start = i * chunkSize;
    const end = Math.min(file.size, start + chunkSize);
    const chunk = file.slice(start, end);
    // 这里可以执行上传操作
}
  1. 断点续传标识生成:通过文件的名字、大小和哈希值生成唯一标识符。例如:
javascript 复制代码
function generateIdentifier(file) {
    return `${file.name}-${file.size}-${file.lastModified}`;
}
  1. MD5 校验:使用 js-md5 库或 Web Cryptography API 实现分块的 MD5 校验:
javascript 复制代码
async function calculateMD5(fileChunk) {
    const arrayBuffer = await fileChunk.arrayBuffer();
    const hashBuffer = await crypto.subtle.digest('MD5', arrayBuffer);
    const hashArray = Array.from(new Uint8Array(hashBuffer));
    const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
    return hashHex;
}
  1. 并发上传:通过 Promise.all 同时上传多个分块提高上传速度:
javascript 复制代码
const promises = [];
for (let i = 0; i < totalChunks; i++) {
    const chunk = file.slice(i * chunkSize, (i + 1) * chunkSize);
    const promise = uploadChunk(chunk);
    promises.push(promise);
}
await Promise.all(promises);
  1. 进度监控:使用 XMLHttpRequest 或 Fetch API 的进度事件,可以更新前端界面的上传进度条。例如:
javascript 复制代码
function uploadChunk(chunk) {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open('POST', '/upload', true);
        xhr.upload.addEventListener('progress', (event) => {
            if (event.lengthComputable) {
                const percentComplete = (event.loaded / event.total) * 100;
                console.log(`Chunk upload: ${percentComplete}% complete`);
            }
        });
        xhr.onload = () => {
            if (xhr.status === 200) {
                resolve(xhr.responseText);
            } else {
                reject(new Error('Chunk upload failed'));
            }
        };
        xhr.send(chunk);
    });
}

怎么用 JS 实现大型文件上传?要考虑哪些问题?

在前端实现大型文件上传,需要考虑以下几个问题:

  • 分片上传:将大文件切割成多个小块进行上传,可以避免一次性上传大文件导致的上传时间过长,网络中断等问题。通常情况下,每个块大小为 1MB 左右。
  • 断点续传:由于网络等因素,上传过程中可能出现中断,此时需要能够从中断的地方恢复上传。
  • 并发上传:多个文件同时上传,需要对上传队列进行管理,保证上传速度和顺序。
  • 上传进度显示:及时显示上传进度,让用户知道上传进度和状态。

可以通过使用第三方库来实现大型文件上传,比如 Plupload、Resumable.js 等。

以下是一个使用 Plupload 实现大型文件上传的示例:

html 复制代码
<!-- 引入 Plupload 的 JavaScript 和 CSS 文件 -->
<script type="text/javascript" src="plupload.full.min.js"></script>
<link rel="stylesheet" href="plupload.css">

<!-- 上传控件的容器 -->
<div id="uploader">
    <p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
</div>
<!-- 初始化上传控件 -->
<script type="text/javascript">
var uploader = new plupload.Uploader({
    browse_button: 'uploader', // 上传控件的容器
    url: '/upload', // 上传文件的 URL
    multi_selection: false, // 是否允许同时上传多个文件
    filters: {
        max_file_size: '100mb', // 最大上传文件大小
        mime_types: [
            { title: 'Image files', extensions: 'jpg,jpeg,gif,png' },
            { title: 'Zip files', extensions: 'zip,rar' }
        ]
    },
    init: {
        // 添加文件到上传队列之前触发的事件
        BeforeUpload: function (up, file) {
            console.log('BeforeUpload:', file.name);
        },
        // 开始上传文件时触发的事件
        UploadFile: function (up, file) {
            console.log('UploadFile:', file.name);
        },
        // 上传进度改变时触发的事件
        UploadProgress: function (up, file) {
            console.log('UploadProgress:', file.percent);
        },
        // 上传成功时触发的事件
        FileUploaded: function (up, file, info) {
            console.log('FileUploaded:', file.name, info.response);
        },
        // 上传出错时触发的事件
        Error: function (up, err) {
            console.log('Error:', err.message);
        }
    }
});

// 初始化上传控件
uploader.init();
</script>

在后端,需要根据上传控件发送的请求,来实现文件的接收和存储。具体实现方式视具体情况而定,可以使用 SpringMVC、Express.js 等框架来实现。同时,也需要考虑上传文件大小限制、上传速度控制等问题。

相关推荐
wangpq5 分钟前
微信小程序地图callout气泡图标在ios显示,在安卓机不显示
前端·vue.js
curdcv_po8 分钟前
Vue3 组件通信方式全解析
前端
Auroral15613 分钟前
基于RabbitMQ的异步通知系统设计与实现
前端·后端
栗筝i13 分钟前
Spring 核心技术解析【纯干货版】- XV:Spring 网络模块 Spring-Web 模块精讲
前端·网络·spring
打野赵怀真16 分钟前
H5如何禁止动画闪屏?
前端·javascript
zhangxingchao16 分钟前
关于浮点数的思考
前端
Riesenzahn16 分钟前
你喜欢Sass还是Less?为什么?
前端·javascript
玄魂17 分钟前
基于Vue框架的开源大屏项目实践
前端·开源·数据可视化
晴殇i18 分钟前
一行代码解决跨域问题,JavaScript新特性解析
前端
挖稀泥的工人22 分钟前
面试看这一篇webpack
前端·webpack