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

Drupal 9/10自定义文件路由遇404问题求助

Drupal 9/10 中 /system/files 路由机制与自定义实现指南

一、/system/files 核心工作流程

核心的/system/files路由是Drupal处理公共文件访问的入口,流程分为三步:

  1. 路由匹配前置处理:核心的PathProcessorFiles入站路径处理器会拦截/system/files/xxx/yyy.txt这类路径,提取xxx/yyy.txt作为filepath参数存入请求,同时将路径替换为/system/files,让路由系统能匹配到system.files路由。
  2. 路由定义:system.files路由的路径为/system/files/{filepath},其中filepath通过options.parameters.filepath.type: path配置允许包含斜杠,确保多级子目录能被正确识别。
  3. 控制器逻辑:FilePublicDownloadController::download()接收filepath参数,加载对应文件实体,校验文件的公开访问权限,最终返回流式响应输出文件内容。

二、自定义路由404问题排查

你已经配置了路径处理器、服务、控制器和路由但仍出现404,大概率是以下环节缺失:

  • 路由占位符配置错误:必须在路由的options里声明filepath的类型为path,否则Drupal会把斜杠当作路由分隔符,无法匹配多级路径。示例路由配置:
    some.prefix.files:
      path: '/some/prefix/{filepath}'
      defaults:
        _controller: '\Drupal\your_module\Controller\CustomFileDownloadController::download'
      requirements:
        _permission: 'access custom file downloads' # 替换为你的自定义权限
      options:
        parameters:
          filepath:
            type: 'path'
    
  • 路径处理器优先级与逻辑问题:确保你的路径处理器优先级高于核心的PathProcessorFiles(核心优先级为0,建议设为10),且逻辑正确:将/some/prefix/aaa/bbb.txt替换为/some/prefix,同时把aaa/bbb.txt存入请求属性。示例处理器代码:
    class CustomPathProcessorFiles implements InboundPathProcessorInterface {
      public function processInbound($path, Request $request) {
        $prefix = '/some/prefix/';
        if (strpos($path, $prefix) === 0 && strlen($path) > strlen($prefix)) {
          $filepath = substr($path, strlen($prefix));
          $request->attributes->set('filepath', $filepath);
          return '/some/prefix';
        }
        return $path;
      }
    }
    
  • 缓存未清空:修改路由或路径处理器后,必须执行drush cr或通过后台清空缓存,否则旧的路由配置会持续生效。

三、FileDownloadController::download() 参数获取方式

核心控制器的参数获取逻辑很直接:

  • 路由占位符直接注入:方法签名public function download(Request $request, $filepath = '')中的$filepath由路由系统自动注入,对应路径处理器解析后的文件路径。
  • Request属性获取:也可以通过$request->attributes->get('filepath')拿到相同的filepath值,两种方式等价。
  • 额外查询参数:如果是私有文件路由,还会通过$request->query->get('file')获取签名验证参数,但公共文件场景主要依赖filepath参数。

四、扩展为 /some/prefix/{node}/{filepath} 的注意事项

后续扩展带节点ID的路由时,需要注意以下几点:

  1. 路由实体占位符配置:把{node}声明为实体类型占位符,让Drupal自动加载节点实体,示例路由:
    some.prefix.node.files:
      path: '/some/prefix/{node}/{filepath}'
      defaults:
        _controller: '\Drupal\your_module\Controller\CustomNodeFileDownloadController::download'
      requirements:
        _entity_access: 'node.view' # 基于节点的访问控制
        node: '\d+'
      options:
        parameters:
          node:
            type: 'entity:node'
          filepath:
            type: 'path'
    
  2. 路径处理器调整:解析路径时要拆分出节点ID和文件路径,比如/some/prefix/123/aaa/bbb.txt要提取123作为node参数,aaa/bbb.txt作为filepath,并返回/some/prefix/123让路由匹配。
  3. 双重权限校验:控制器里既要校验文件的访问权限,也要校验当前用户是否有权限查看对应的节点,比如$node->access('view', \Drupal::currentUser())。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 15:37:00