用JS怎么把本地文件上传到服务器,有哪些方法?

用JS将本地文件上传到服务器,核心思路是借助FormData封装文件数据,再通过fetch或XMLHttpRequest发异步请求,后端(如Node.js、Java)解析二进制流并落盘。实际项目里还要考虑大文件分片、进度条、断点续传和跨域限制,下面按不同场景逐个说清。

js上传文件到服务器代码示例:从基础写法讲起

先看最简洁的版本,页面里放一个文件选择框,选完自动触发上传:

js文件上传和项目实战
加载中
js文件上传和项目实战
document.getElementById('fileInput').addEventListener('change', async (e) => {
  const file = e.target.files[0];
  if (!file) return;
  const formData = new FormData();
  formData.append('file', file);
  const res = await fetch('/upload', {
    method: 'POST',
    body: formData
  });
  const data = await res.json();
  console.log('上传成功', data.url);
});

这段代码核心就三件事:把文件塞进FormData、用fetch发送、解析后端返回的地址。FormData会自动生成multipart/form-data请求体,别手动去设置Content-Type,边界符交给浏览器生成即可。

用XMLHttpRequest实现带进度条的上传

fetch虽然写起来爽,但它没有原生上报上传进度的接口,想要进度条,得退回XMLHttpRequest的upload.onprogress事件:

const xhr = new XMLHttpRequest();
xhr.open('POST', '/upload');
xhr.upload.onprogress = (e) => {
  if (e.lengthComputable) {
    const percent = Math.round((e.loaded / e.total)  100);
    document.getElementById('bar').style.width = percent + '%';
  }
};
xhr.onload = () => {
  if (xhr.status === 200) {
    console.log('上传完成');
  }
};
xhr.send(formData);

业界做上传组件(比如webuploader)底层基本都是这套逻辑,区别在于封装程度:库帮你处理了并发、重试和队列,原理还是XMLHttpRequest。

多文件上传和Blob上传的拓展

  • 多文件:给<input>加上multiple属性,循环遍历e.target.files
  • Blob切片:File本身就是Blob的子类,所以也能直接传二进制数据
  • 上传文本:新建new Blob([str])后塞进FormData,同样能到达服务器

javascript大文件上传解决方案:分片、断点、并发控制

大文件和大文件是两个概念。单文件超过几百MB,一次POST丢过去很容易超时或撑爆内存,业内通用的做法是把文件切块,分多次请求上传,最后在服务端拼接。

分片的核心公式

const CHUNK_SIZE = 5  1024  1024; // 每片5MB
let offset = 0;
let chunkIndex = 0;
const chunks = [];
while (offset < file.size) {
  const chunk = file.slice(offset, offset + CHUNK_SIZE);
  chunks.push({
    index: chunkIndex,
    blob: chunk
  });
  offset += CHUNK_SIZE;
  chunkIndex++;
}

获取分片列表之后,用并发池控制上传数量。一般建议并发数控制在3到5个,发太多会打爆服务器的TCP连接,太少又体现不出分片优势。

async function uploadChunks(chunks, fileId) {
  const limit = 3;
  const pool = chunks.splice(0, limit).map(async (chunk) => {
    const fd = new FormData();
    fd.append('file', chunk.blob);
    fd.append('fileId', fileId);
    fd.append('index', chunk.index);
    await fetch('/upload/chunk', { method: 'POST', body: fd });
  });
  await Promise.all(pool);
}

断点续传要解决什么问题

断点续传指的是上传过程中断后,下一次能跳过已上传的分片,方案分两层:

  • 后端记录已完成的分片索引,前端上传前请求一次/upload/status?fileId=xxx
  • 拿到已传列表后,前端过滤掉这些分片再继续传

有的团队用Redis存分片状态,有的直接丢数据库表里。选型取决于服务器资源,并不存在唯一标准。

秒传的实现逻辑

秒传本质上和断点续传共用一套元数据:前端算出文件的MD5(用SparkMD5),后端比对数据库,若已存在则直接返回“上传成功”,拿大文件算MD5会有CPU开销,可以切块算个特征值再合并,速度更快。

用vue axios上传文件到服务器怎么操作?对比原生写法

平时用Vue做后台管理,多半会引进axios。axios在文件上传场景带来的最大增量不是语法,而是拦截器和错误统一处理。

import axios from 'axios';
function uploadAvatar(file) {
  const formData = new FormData();
  formData.append('avatar', file);
  return axios.post('/api/user/avatar', formData, {
    headers: { 'Content-Type': 'multipart/form-data' },
    timeout: 30000,
    onUploadProgress: (e) => {
      if (e.lengthComputable) {
        this.progress = Math.round((e.loaded / e.total)  100);
      }
    }
  });
}

对比原生fetch,axios的收益有三个显性点:

  • 请求拦截器:自动在Header里带Token
  • 响应拦截器:统一处理401跳转或服务器返回的业务错误码
  • 取消请求:通过AbortController或CancelToken中断上传

拖拽上传交互的写法

真正让上传体验“现代感”的是拖拽上传,事件核心是dragover和drop:

dropZone.addEventListener('dragover', (e) => {
  e.preventDefault(); // 阻止浏览器默认打开文件
});
dropZone.addEventListener('drop', (e) => {
  e.preventDefault();
  const files = Array.from(e.dataTransfer.files);
  files.forEach(uploadFile);
});

拿到File对象列表后,后续处理和<input>选择的一模一样,用URL.createObjectURL(file)还能生成本地预览地址,做缩略图展示非常方便。

图片上传前压缩

手机拍的照片动辄几MB,直接传浪费流量也拖慢速度,前端可用Canvas把图片缩到最大边2000px后转成Blob:

canvas.toBlob((blob) => {
  const newFile = new File([blob], file.name, { type: file.type });
  upload(newFile);
}, 'image/jpeg', 0.8);

能显著降低文件体积,服务器存储成本也减少,属于性价比很高的优化手段。

node.js怎么接收前端上传的文件?后端配置参考

搜“js上传文件到服务器”的人,一半卡在前端,另一半卡在后端接不住,以Node.js生态为例,最常用的接收工具是multer。

Express + multer的样板代码

npm install express multer
const express = require('express');
const multer = require('multer');
const upload = multer({
  dest: 'uploads/',
  limits: { fileSize: 100  1024  1024 }
});
const app = express();
app.post('/upload', upload.single('file'), (req, res) => {
  // req.file 包含文件名、大小、路径等元信息
  res.json({
    url: '/uploads/' + req.file.filename
  });
});
app.listen(3000);

注意:upload.single('file')里的'file'必须和前端FormData.append的key完全一致,若是多文件用upload.array('file', 10)。

大文件分片在服务端的合并

后端收到分片后需要按索引合并,常用做法是先存临时目录,全部到齐后读取拼接:

const fs = require('fs');
function mergeChunks(fileId, total, dest) {
  const writeStream = fs.createWriteStream(dest);
  for (let i = 0; i < total; i++) {
    const chunkPath = `uploads/tmp/${fileId}-${i}`;
    writeStream.write(fs.readFileSync(chunkPath));
  }
  writeStream.end();
}

更高效的方案用Stream管道逐个写入,避免内存中同时塞入多个大对象。

生产环境不直接让Node写静态文件

实际部署时,上传目录通常由Nginx映射,请求进来后绕开Node进程直接读文件,原因很简单:Node的I/O吞吐不如Nginx高效,而且文件下载会长时间占用进程资源。

方案 服务器流量占用 上传速度 开发复杂度
前端直传对象存储(OSS/COS) 不经过业务服务器 快(走CDN边缘) 中
通过自家Node中转 全部流量走服务器 受带宽限制 低
Nginx直接接收并转发 需做模块扩展 较快 高

若项目流量不大,选中转方案开发速度最快。当用户量和文件体积增长后,再迁到对象存储直传,这在业内是非常成熟的技术路径。

服务器租用价格之外,还要操心这些坑

如果你在考虑“js上传文件服务器租用价格多少”这类问题,先别急着比价。便宜服务器往往带宽也小,而上传场景最吃带宽,简米云、酷番云的轻量服务器,入门配置的年费多数在几百元区间(具体随活动波动),但流量包超出后额外计费。

选择地域时,按用户分布来:用户集中在华南,选广州节点;集中在华东,选上海或杭州节点,距离近了,网络延迟能降不少。

上传失败自查清单

  • 跨域问题:服务器响应头需包含Access-Control-Allow-Origin
  • 大小限制:Nginx默认client_max_body_size只有1MB,需调整为50m或更高
  • Content-Type:截获请求体确认是multipart/form-data,不能是纯二进制流
  • DNS解析:内网环境用IP直连,外网请求确认域名已备案且能正常解析

文件校验别只看扩展名

扩展名可以伪装成图片,但文件头(Magic Number)不会说谎:

  • PDF文件头固定为%PDF
  • PNG文件头固定为\x89PNG
  • JPEG文件头固定为\xFF\xD8\xFF

读前几个字节校验文件类型,能挡掉相当一部分杂七杂八的上传,同时将文件名改为随机字符串存盘,避免用户上传带路径或特殊字符的文件名引发安全风险。

关于js上传文件的常见问题解答

fetch和axios做文件上传,选哪个好?

fetch是浏览器内置API,零依赖,写小功能非常轻快;axios支持拦截器、取消请求和更细的进度控制,团队协作项目用axios能减少重复代码,两者底层传输能力等价,区别在生态和封装度。

大文件上传中途断网了,重传必须从零开始吗?

不需要,按上文分片方案把文件切块后,上传前先向后端查询已收到的分片索引,过滤掉已完成的部分,再把剩余分片传完,后端拼合即可。

对象存储直传和自建服务器上传,怎么权衡?

需求量不大时自建完全够用,成本是服务器带宽,文件量大且用户分布广,直传OSS/COS能把流量分散到CDN节点,提升上传速度的同时缓解源站压力,缺点是按量计费,得拉账单评估成本。

首发原创文章,作者:王坚‌,如若转载,请注明出处:https://idctop.com/article/771008.html

赞 (0)
上一篇 2026年10月21日 07:09
下一篇 2026年10月21日 07:09

相关推荐

  • AI人工智能算法有哪些,人工智能算法原理是什么

    在数字化转型的浪潮中,人工智能算法已成为驱动现代科技进步的核心引擎,它不仅是计算机代码的堆砌,更是模拟人类认知、处理海量数据并实现决策智能化的逻辑集合,从底层的机器学习到上层的行业应用,ai人工智能算法正在重塑各行各业的业务流程,将数据资产转化为可执行的商业价值,其核心本质在于通过数学模型寻找数据中的规律,从而……

    2026年2月24日
    13200
  • 如何做出更高级的数据可视化?数据可视化软件哪个好用

    更高级的数据可视化并非单纯追求视觉炫技,而是通过交互设计与叙事逻辑,将复杂数据转化为可执行的商业洞察,从而显著提升决策效率与数据理解深度,传统报表往往让数据沉睡在静态图表中,而现代可视化技术正在打破这一僵局,它不再只是把数字变成柱状图或饼图,而是构建一个动态的数据探索环境,在这种环境下,用户不再是被动接收信息……

    2026年5月26日
    4000
  • 丽萨主机VPS测评,美国双ISP、Tiktok实测数据表现,丽萨主机VPS好用吗

    丽萨主机VPS凭借美国双ISP线路优化与TikTok低延迟实测表现,是目前2026年跨境短视频运营与多账号矩阵搭建的高性价比首选方案,其核心优势在于稳定的IP纯净度与针对流媒体平台的专项网络优化,基础设施与网络架构深度解析双ISP线路的物理优势丽萨主机(Lisa Host)在2026年的产品迭代中,核心卖点聚焦……

    2026年5月17日
    9000
  • Alfa深度学习软件怎么用?深度学习软件哪个好用

    Alfa深度学习软件通过其独特的模块化架构与自适应优化引擎,显著降低了AI模型开发的门槛,成为从科研原型到工业落地的核心工具,在人工智能技术飞速迭代的今天,许多开发者和技术管理者都在寻找一款既能满足高性能计算需求,又具备极高易用性的深度学习平台,Alfa深度学习软件正是在这样的背景下脱颖而出,它不仅仅是一个代码……

    2026年5月30日
    3900
  • asp文件上传进度条如何实现|asp上传进度条插件

    在ASP(Active Server Pages)环境中实现文件上传功能时,用户最常遭遇的痛点之一就是缺乏直观的上传进度反馈,传统的ASP上传方式,用户点击“提交”后只能面对空白页面或静态提示长时间等待,无法知晓文件传输是否正常进行、已完成多少,这种不确定性严重损害用户体验,甚至可能导致用户误操作(如重复提交……

    2026年2月7日
    11800
  • AIoT时代新技术布局有哪些?AIoT新技术布局方案解析

    在AIoT时代,新技术布局的核心在于构建“端-边-云-网-智”五位一体的协同生态,通过智能化与互联化的深度融合,实现技术价值最大化,企业需以数据为驱动,以场景为导向,优先布局边缘计算、AI芯片、低功耗广域网等关键技术,同时强化安全体系与标准化建设,才能在竞争中占据先机,边缘计算成为AIoT技术布局的关键节点边缘……

    2026年3月20日
    10400
  • 苹果6ID注册服务器失败为什么,怎么解决?

    苹果6 id注册服务器失败,核心结论是:这不是手机硬件坏了,而是网络验证链路或Apple服务器策略导致的数据交互中断,极少数情况与系统版本过旧有关,iPhone 6发布至今已超过十年,当它提示“注册服务器失败”时,用户很容易以为是设备太老扛不动新系统,ID注册依赖的是Apple的验证通道,和手机算力关系不大,搞……

    2026年8月29日
    400
  • Excel下拉公式怎么快速填充?批量填充数据方法

    在Excel中实现下拉公式快速填充,最核心的方法是使用快捷键Ctrl+D或双击单元格右下角的填充柄,这比鼠标拖拽效率高出数倍,能瞬间完成整列数据的公式同步,很多职场人在处理表格时,面对成百上千行的数据,如果还坚持用鼠标逐个下拉,不仅耗时耗力,还容易因手抖导致公式引用错误,Excel提供了多种“秒级”填充方案,掌……

    2026年7月7日
    23100
  • 广州虚拟主机时间不同步怎么办,广州虚拟主机时间同步如何设置

    广州虚拟主机时间同步的核心在于通过NTP/PTP协议集群,对接国家授时中心标准源,并针对华南网络链路进行延迟补偿,以实现毫秒级甚至微秒级的时钟精度,彻底消除因时间漂移导致的业务宕机与数据合规风险,时间失准的隐性代价与同步底层逻辑为什么广州节点必须重视时钟同步?在分布式架构主导的2026年,虚拟主机的时间戳早已不……

    2026年4月27日
    5100
  • 服务器1m的宽带够用吗?1m带宽能带多少人访问

    服务器1m的宽带通常指服务器公网带宽为1Mbps,其核心价值在于极低的成本投入与基础运维需求的完美平衡,对于低并发、静态资源为主的初级应用场景,它是性价比最高的选择,但对于高并发或大流量业务,则必须升级带宽或采用加速方案,判定其是否够用的关键指标,在于业务类型、用户访问量及页面优化程度,而非单纯看带宽数值,1m……

    2026年4月7日
    10200

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注