用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

相关推荐

  • 苹果手机6s微信定位服务器怎么设置,详细步骤有哪些?

    苹果iPhone 6s无法手动切换微信定位服务器,所谓“定位服务器”实际是系统网络定位服务的自动调度机制,用户能做的不是“切换”,而是通过修正系统设置、网络环境和应用权限来让微信重新连接到正常节点,很多手持iPhone 6s的朋友在微信定位不准、附近的人刷不出来时,会搜到各种“修改定位服务器”的教程,结果发现要……

    2026年10月2日
    100
  • CS2服务器负载过高怎么办,游戏卡顿延迟高如何解决?

    遇到CS2提示服务器负载过高,先别急着反复重连——核心做法是分清场景:官方匹配高峰期拥堵就错峰或放宽延迟上限,第三方平台拥挤就换区,社区服人满就换服,必要时切换加速器节点,cs2服务器负载过高怎么解决:先分清场景再动手每次弹负载过高的提示,先看一眼你正在连的是哪一类服务器,官方匹配(竞技、休闲、死斗)走的是V社……

    2026年10月12日
    100
  • 安徽联通IPv6 VPS月付15.8起好用吗?安徽联通IPv6 VPS推荐

    CoalCloud(碳云)新上线的安徽联通IPv6 VPS以月付¥15.8起的超低门槛,为需要低成本网络环境的用户提供了具备IPv4 NAT入站能力的优质选择,特别适合搭建个人博客、轻量级应用或作为IPv6过渡期的备用节点,在当前的网络环境中,纯IPv6环境虽然正在普及,但许多老旧服务、特定地区网络或国内访问场……

    2026年6月29日
    2000
  • 广电网vps怎么样?广电网vps哪家好

    在2026年严格的网络合规环境下,广电网VPS是依托国家广电骨干网络构建的云服务器,它以原生IP的极高纯净度与直连骨干网的超低延迟,成为直播、矩阵营销与数据采集中降低封禁风险的最优基础设施,广电网VPS的核心壁垒与底层架构区别于传统电信联通的物理链路广电网VPS并非简单租用机房,而是深度接入中国广播电视网络集团……

    2026年4月24日
    7300
  • ajax加载大量数据库卡顿怎么办?如何优化前端数据加载性能

    AJAX加载大量数据库的核心在于采用分页加载、虚拟滚动或无限滚动技术,结合后端接口优化,以平衡用户体验与服务器性能,避免页面卡顿,当用户面对成千上万条数据时,传统的整页加载方式早已成为历史,浏览器需要一次性解析巨大的DOM树,这不仅消耗内存,更会导致主线程阻塞,让页面在几秒钟内毫无反应,现代Web开发中,通过A……

    2026年6月4日
    3800
  • AI智能区块链怎么样,人工智能区块链未来发展前景如何?

    AI与区块链的深度融合,正在构建下一代可信数字基础设施的底层逻辑,这种技术融合并非简单的叠加,而是通过区块链的不可篡改性与去中心化特性,解决了人工智能发展中的数据孤岛、算法黑箱与隐私泄露等核心痛点;利用人工智能的强大算力与自动化能力,弥补了区块链在处理效率与智能决策上的不足,从专业维度评估,AI智能区块链怎么样……

    2026年2月24日
    13600
  • 轻量应用服务器怎么搭建sk5?,有哪些操作步骤

    轻量应用服务器搭建sk5(SOCKS5代理)的核心答案:选择Linux系统(如Ubuntu/CentOS),通过SSH登录后安装dante-server或3proxy,配置端口、认证方式并开放防火墙即可完成部署,整个过程约15分钟,轻量应用服务器怎么搭建sk5教程选对轻量服务器比配置更重要搭建sk5之前,先确认……

    2026年9月7日
    300
  • V.PS荷兰大硬盘VPS值得买吗,荷兰VPS推荐哪家稳定

    V.PS推出的荷兰大硬盘VPS以€47.96/年的超低价格提供1核2G配置及500G存储,是追求高性价比与数据安全的理想选择,在服务器租赁市场日益内卷的当下,寻找一款既便宜又稳定的VPS并非易事,V.PS近期上线的这款荷兰节点产品,凭借阿姆斯特丹机房的网络优势和极具竞争力的定价策略,迅速在技术圈和建站爱好者中引……

    2026年6月25日
    2200
  • 南京短视频平台大宽带流量费怎么省?,服务器带宽价格如何谈?

    南京本地做短视频矩阵和直播带货的团队,想省大宽带服务器流量费,核心思路就一句话:别让流量在源站和回源链路上烧钱,把八成以上的请求拦截在边缘节点和缓存层,同时按真实业务曲线选对计费模式,短视频平台流量费为什么总是超预算做南京本地生活账号或者直播切片分发的朋友,月底对账单时经常发现,流量费比服务器租用费还高,这背后……

    2026年9月20日
    100
  • 阴阳师iso服务器登录不上怎么办,登录失败原因及解决?

    阴阳师iOS服务器登录不上时,最快的解决路径是依次检查App Store版本更新、当前网络运营商状态和官方公告中的服务器维护安排,多数情况下能在半小时内自行恢复,为什么你的阴阳师iOS端突然连不上服务器游戏进不去的第一时间,玩家最容易怀疑是自己的手机出了问题,根据近年来的玩家反馈统计,阴阳师iOS服务器登录不上……

    2026年9月21日
    100

发表回复

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