You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

任意类型文件无限制上传至服务器的代码实现与NGINX配置

任意类型无大小限制文件上传实现方案(Nginx+HTML+JS+PHP)

一、Nginx上传限制配置调整

Nginx默认自带上传大小限制,核心控制参数是client_max_body_size,默认值为1MB,超过阈值的请求会直接返回413状态码。要关闭大小限制按以下步骤操作:

  • 定位Nginx配置文件,全局配置一般在/etc/nginx/nginx.conf,站点单独配置通常在/etc/nginx/conf.d/或/etc/nginx/sites-available/目录下对应域名的conf文件中。
  • 在http块(全局生效)、server块(单站点生效)或对应上传接口的location块(单接口生效)中添加以下配置,配置优先级为location > server > http:
# 设为0即为完全禁用上传大小检查,如需设置阈值可写为10240m(对应10GB)这类值
client_max_body_size 0;
# 大文件传输需要调大超时时间,避免传输中途连接断开
client_body_timeout 300s;
send_timeout 300s;
# 如果Nginx做反向代理转发请求到后端服务,需要额外加这行
proxy_read_timeout 300s;
# 确认请求体临时存储路径有Nginx运行用户的写入权限,避免大文件临时写入失败
client_body_temp_path /var/nginx/client_body_temp;
  • 先执行nginx -t检查配置语法是否正确,确认无误后执行nginx -s reload重载配置生效。

注意:公网生产环境不建议完全关闭上传大小限制,无鉴权的无限制上传很容易被恶意攻击者传大文件占满服务器磁盘,直接导致服务不可用,建议根据业务需求设置合理阈值,必须开无限制的话一定要做好接口鉴权和磁盘配额监控

二、前端代码实现(HTML+JavaScript)

前端通过FormData传递文件,用XMLHttpRequest实现上传进度监听,基础可运行代码如下:

<!-- 上传区域 -->
<input type="file" id="filePicker" accept="*">
<button id="startUpload">上传文件</button>
<div style="width: 500px;height: 20px;border: 1px solid #eee;margin: 10px 0;">
  <div id="progress" style="width: 0%;height: 100%;background: #2385bb;"></div>
</div>
<p id="statusTip"></p>
const filePicker = document.getElementById('filePicker');
const startUpload = document.getElementById('startUpload');
const progress = document.getElementById('progress');
const statusTip = document.getElementById('statusTip');

startUpload.addEventListener('click', () => {
  const file = filePicker.files[0];
  if (!file) {
    statusTip.textContent = '请先选择要上传的文件';
    return;
  }
  const formData = new FormData();
  formData.append('targetFile', file);
  formData.append('originName', file.name);

  const xhr = new XMLHttpRequest();
  // 监听上传进度
  xhr.upload.onprogress = (e) => {
    if (e.lengthComputable) {
      const percent = ((e.loaded / e.total) * 100).toFixed(1);
      progress.style.width = `${percent}%`;
      statusTip.textContent = `上传中:${percent}%`;
    }
  };
  // 上传完成回调
  xhr.onload = () => {
    if (xhr.status === 200) {
      const res = JSON.parse(xhr.responseText);
      statusTip.textContent = res.msg;
    } else {
      statusTip.textContent = `上传失败,状态码:${xhr.status}`;
    }
  };
  // 上传错误回调
  xhr.onerror = () => {
    statusTip.textContent = '网络异常,上传失败';
  };
  xhr.open('POST', './upload.php');
  xhr.send(formData);
});

单文件大小超过10G的场景,建议加分片上传逻辑:把文件按固定大小(比如10MB/片)切割,带分片序号逐片上传,后端接收完全部分片后按序号合并成完整文件,能避免网络波动导致整文件重传,同时降低服务端内存占用。

三、后端PHP实现

PHP本身也有默认上传大小限制,只改Nginx配置不调整PHP配置的话,大文件上传依然会失败,先调整php.ini配置:

  • 找到对应运行模式的php.ini文件,php-fpm模式下配置路径一般为/etc/php/{版本号}/fpm/php.ini,修改以下参数:
; POST请求最大大小限制,设为0为不限制
post_max_size = 0
; 单上传文件最大大小限制,设为0为不限制
upload_max_filesize = 0
; 内存限制,大文件上传场景建议设为-1(不限制),避免内存不足报错
memory_limit = -1
; 脚本最大执行时间、输入时间设为0(不限制),避免大文件传输过程中脚本超时退出
max_execution_time = 0
max_input_time = 0
  • 重启php-fpm服务生效,比如PHP8.1版本执行systemctl restart php8.1-fpm即可。
  • 新建upload.php处理上传请求,代码如下:
<?php
header('Content-Type: application/json;charset=utf-8');
// 提前创建uploads目录,给Nginx和PHP运行用户分配该目录的读写权限
$savePath = __DIR__ . '/uploads/';
if (!is_dir($savePath)) {
    mkdir($savePath, 0755, true);
}

if (!isset($_FILES['targetFile'])) {
    echo json_encode(['code' => 1, 'msg' => '未接收到上传文件']);
    exit;
}

$uploadFile = $_FILES['targetFile'];
$fileName = $_POST['originName'] ?? $uploadFile['name'];
// 过滤文件名非法字符,防范路径遍历漏洞
$fileName = preg_replace('/[^\w\.\-\x{4e00}-\x{9fa5}]/u', '', $fileName);
$targetFile = $savePath . $fileName;

// 处理上传错误
if ($uploadFile['error'] !== UPLOAD_ERR_OK) {
    $errorMap = [
        UPLOAD_ERR_INI_SIZE => '文件大小超过php.ini配置限制',
        UPLOAD_ERR_FORM_SIZE => '文件大小超过表单限制',
        UPLOAD_ERR_PARTIAL => '文件传输不完整',
        UPLOAD_ERR_NO_TMP_DIR => '服务端临时目录不存在',
        UPLOAD_ERR_CANT_WRITE => '文件写入磁盘失败'
    ];
    echo json_encode(['code' => 1, 'msg' => $errorMap[$uploadFile['error']] ?? '未知上传错误']);
    exit;
}

if (move_uploaded_file($uploadFile['tmp_name'], $targetFile)) {
    echo json_encode(['code' => 0, 'msg' => "文件上传成功,保存路径:{$targetFile}"]);
} else {
    echo json_encode(['code' => 1, 'msg' => '文件保存失败,请检查目录权限']);
}
?>

四、落地注意事项

  • 无限制上传风险极高:公网环境下必须给上传接口加鉴权(比如登录态校验、签名校验),禁止匿名上传,同时给上传目录设置磁盘配额,避免磁盘被写满导致服务宕机。
  • 所有配置修改后必须重载/重启对应服务才会生效,建议先用小文件验证全流程正常,再测试大文件上传。
  • 超过2G的文件上传,建议优先选择分片+断点续传方案,稳定性远高于整文件上传。

内容的提问来源于stack exchange,提问作者Michael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 00:33:23