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

TP-Link TL-WR940N路由器表单上传文件时拦截IP问题求助

问题背景

使用TP-Link TL-WR940N路由器时,无论是表单批量上传还是改成AJAX逐个上传图片,IP都会被路由器防火墙拦截。怀疑和路由器的三个洪水攻击过滤选项有关:

  • ICMP-FLOOD Attack Filtering
  • UDP-FLOOD Filtering
  • TCP-SYN-FLOOD Attack Filtering

可能的原因与解决方案

1. 路由器洪水过滤误触发

TL-WR940N的这三个过滤功能阈值默认设置可能过低,即使是正常的AJAX连续请求也会被判定为攻击:

  • TCP-SYN-FLOOD是核心嫌疑:你的AJAX是TCP POST请求,虽然是串行发起,但路由器可能对单位时间内的连接数/请求数限制过严,误判为SYN洪水攻击。
  • 临时验证方案:先临时关闭这三个过滤选项,测试是否还会被拦截。如果问题消失,说明是过滤阈值过高导致误判。
  • 长期解决:进入路由器后台(通常为192.168.0.1或192.168.1.1),找到「安全设置」-「攻击防护」,调高三个过滤的阈值(比如TCP SYN的连接数阈值),或者把你的服务器/客户端IP加入路由器的IP白名单,直接跳过过滤检测。

2. AJAX请求特性优化

即使是串行请求,浏览器的连接复用或请求间隔过短也可能触发路由器检测:

  • 在AJAX请求之间添加短暂延迟,给路由器足够的时间处理完上一个请求,避免被判定为连续攻击:
    // 在success回调的递归调用前添加延迟
    setTimeout(function() {
      uploadFileAsync(idProduct, alt, iteration, files);
    }, 500); // 延迟500毫秒,可根据实际情况调整
    
  • 开启AJAX连接复用,减少TCP连接的频繁建立:
    $.ajax({
      // ...其他配置
      xhrFields: {
        withCredentials: true // 开启连接复用
      },
      headers: {
        'Connection': 'keep-alive'
      }
    })
    

3. 代码潜在问题优化

前端JS代码调整

你的JS中formData.delete('fileGal[]')属于冗余操作(每次调用都会新建FormData),同时建议添加错误处理避免请求失败后无限递归:

function uploadFileAsync(idProduct, alt, iteration, files) {
  var formData = new FormData();
  var arrFilesLength = files.length;
  var file = files[iteration]; 

  formData.set('fileGal[]', file, file.name);

  $.ajax({        
    url: documentDomain + 'admin.php?uploadFile=' + idProduct + '&imgAlt=' + alt,
    type: 'POST',
    async: true,
    data: formData,
    cache: false,
    contentType: false,
    processData: false,
    xhrFields: {
      withCredentials: true
    },
    success: function(data) {
      iteration++;
      if (iteration == arrFilesLength) {
        $('progress').css('display', 'none');
        $('.fileGal').val('');
        $('.imurConvertGood').hide();
        $('.productGalleryTitle').html('No file');
        refreshPicturesList(idProduct);
      } else {
        $('progress').attr({
          value: iteration,
          max: arrFilesLength,
        });
        setTimeout(() => uploadFileAsync(idProduct, alt, iteration, files), 500);
      }
    },
    error: function(xhr, status, err) {
      console.error('上传失败:', err);
      alert('第' + (iteration+1) + '个文件上传失败,请重试');
    }
  });
}

后端PHP代码调整

原代码中的递归调用$this->uploadFile($idProduct, $fi)可能导致后端处理时间过长,间接让路由器认为连接异常,建议改成循环:

private function uploadFile($idProduct = null, $imgAlt = null) {
  $config = new Config;
  $idProduct = htmlspecialchars($idProduct, ENT_QUOTES);
  $pathFilesServer = $this->AppModel->pathFilesServer();

  $productSQL = $this->AppModel->selectData('products', array('name', 'aliasID'), array('id' => $idProduct));
  $productArr = $productSQL->fetch_assoc();

  $aliasNameSQL = $this->AppModel->selectData('alias', 'alias', array('id' => $productArr['aliasID']));
  $aliasName = $aliasNameSQL->fetch_assoc();  

  $filesCount = is_array($_FILES['fileGal']['name']) ? count($_FILES['fileGal']['name']) : 1;
  
  // 用循环替代递归
  for ($fi = 0; $fi < $filesCount; $fi++) {
    if (is_array($_FILES['fileGal']['name'])) {
      $file_name = $_FILES['fileGal']['name'][$fi];
      $file_tmp = $_FILES['fileGal']['tmp_name'][$fi];
    } else {
      $file_name = $_FILES['fileGal']['name'];
      $file_tmp = $_FILES['fileGal']['tmp_name'];
    }

    $file_name = strtolower($file_name);

    /* 生成新文件名 */
    $today = getdate();
    $md=md5($today[0]+rand());
    $tmp = explode(".", $file_name);
    $extension = end($tmp);

    if ($aliasName['alias'] != '') {
      $newName = $aliasName['alias'].'-'.rand(1000, 9999).'.'.$extension;
    } else {
      $newName = $md.'.'.$extension;
    }

    $path = $pathFilesServer.'/Store/imgProducts/orginal/'.$newName;

    // 生成缩略图
    $fileFromImagick = $this->helpers->resizeImage($file_tmp, 250, 250, Imagick::FILTER_LANCZOS, 1, true, null);
    file_put_contents ($pathFilesServer.'/Store/imgProducts/min/'.$newName, $fileFromImagick);

    $fileFromImagick = $this->helpers->resizeImage($file_tmp, 500, 500, Imagick::FILTER_LANCZOS, 1, true, null);
    file_put_contents ($pathFilesServer.'/Store/imgProducts/middle/'.$newName, $fileFromImagick);

    // 上传原文件
    if(is_uploaded_file($file_tmp)) { 
      move_uploaded_file($file_tmp, $path); 
    }

    // 插入数据库
    $insertData = array(
      'id' => '', 
      'idProduct' => $idProduct, 
      'file' => $newName, 
      'alt' => $imgAlt ?? $productArr['name']
    );
    $this->AppModel->insertValue('pictures', $insertData);
  }
}

总结

优先排查路由器的洪水攻击过滤设置,这是最可能的触发原因;其次优化AJAX请求的间隔与连接复用;最后调整后端代码避免递归带来的长时间连接问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 22:00:58