查看“︁Dokuwiki URL重写”︁的源代码
←
Dokuwiki URL重写
跳转到导航
跳转到搜索
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
最近我在给自己的 DokuWiki 配置 <abbr>URL</abbr> 重写,也就是让原本类似: /doku.php?id=start 这样的地址变成更简洁的: /start 配置过程中,页面本身很快就能正常访问了,但随后遇到了一个比较隐蔽的问题:'''上传的媒体文件、网站 Logo 和部分缩略图无法正常显示'''。 这篇文章记录一下完整排查过程和最终解决方案。 ---- == 一、环境说明 == 我的 DokuWiki 安装路径为: /www/wwwroot/dokuwiki 媒体文件实际存放路径为: /www/wwwroot/dokuwiki/data/media 网站使用:Nginx + PHP + DokuWiki + Cloudflare DokuWiki 媒体文件并不是直接通过 <code>/data/media/xxx.png</code> 访问,而是通过 DokuWiki 的 PHP 程序处理,例如: /_media/logo.png 最终会被重写到: /lib/exe/fetch.php?media=logo.png 这点非常重要,不能为了让图片能访问就直接开放 <code>/data/media</code> 目录。 ---- == 二、最初的 Nginx 重写规则 == 我最初添加了类似下面的规则: location / { try_files $uri $uri/ @dokuwiki; } location @dokuwiki { rewrite ^/_media/(.*) /lib/exe/fetch.php?media=$1 last; rewrite ^/_detail/(.*) /lib/exe/detail.php?media=$1 last; rewrite ^/_export/([^/]+)/(.*) /doku.php?do=export_$1&id=$2 last; rewrite ^/(.*) /doku.php?id=$1&$args last; } 页面访问没有问题,但媒体文件无法访问。 后来发现,问题出在 Nginx 的静态资源缓存规则上。 配置里还有这样的规则: location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; error_log /dev/null; access_log /dev/null; } 而 DokuWiki 的媒体 <abbr>URL</abbr> 是这样的: /_media/logo.png 因为它以 <code>.png</code> 结尾,所以请求会被上面的图片缓存规则提前匹配,Nginx 会尝试直接寻找: /www/wwwroot/dokuwiki/_media/logo.png 但实际文件并不在这个位置,而是在: /www/wwwroot/dokuwiki/data/media/logo.png 因此返回 404。 ---- == 三、修复媒体文件无法访问 == 解决方法是:'''给 <code>/_media/</code>、<code>/_detail/</code>、<code>/_export/</code> 单独写高优先级 location,并放在静态资源缓存规则之前。''' 最终使用的规则如下: location ^~ /_media/ { rewrite ^/_media/(.*)$ /lib/exe/fetch.php?media=$1 last; } location ^~ /_detail/ { rewrite ^/_detail/(.*)$ /lib/exe/detail.php?media=$1 last; } location ^~ /_export/ { rewrite ^/_export/([^/]+)/(.*)$ /doku.php?do=export_$1&id=$2 last; } location / { try_files $uri $uri/ @dokuwiki; } location @dokuwiki { rewrite ^/(.*) /doku.php?id=$1&$args last; } 这里使用了: ^~ 表示只要匹配到这个前缀,就不再继续匹配后面的正则 location。 这样 <code>/_media/logo.png</code> 就不会被图片缓存规则截走,而是会正确交给 DokuWiki 的 <code>fetch.php</code> 处理。 ---- == 四、不要直接开放 data 目录 == DokuWiki 的 <code>data</code>、<code>conf</code>、<code>inc</code>、<code>vendor</code> 等目录不应该被外部直接访问。 可以保留这样的安全规则: location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md|data|conf|bin|inc|vendor) { return 404; } 这样可以防止访问: /data/media/logo.png /conf/local.php /inc/ 媒体文件应通过: /_media/logo.png 由 DokuWiki 控制输出。 ---- == 五、Logo 和缩略图仍然无法显示 == 媒体文件可以直接打开后,我又遇到了第二个问题。 页面中的 Logo 和缩略图仍然无法显示,例如: <'''img''' id="dw__logo" src="/_media/logo.png"> 以及: <'''img''' src="/_media/capture_2025-11-11_185838.png?w=90&h=90&tok=68fe3f"> 但奇怪的是,某些带参数的图片又可以访问: /_media/logo.png?t=1706014361&w=64&h=64&tok=e2dbf1 为了进一步判断问题,我在终端使用 `curl -I` 测试了几个地址: curl -I "<nowiki>https://www.example.com/_media/logo.png</nowiki>" curl -I "<nowiki>https://www.example.com/_media/logo.png?t=1706014361&w=64&h=64&tok=e2dbf1</nowiki>" curl -I "<nowiki>https://www.example.com/lib/exe/fetch.php?media=logo.png</nowiki>" curl -I "<nowiki>https://www.example.com/lib/exe/fetch.php?media=logo.png&t=1706014361&w=64&h=64&tok=e2dbf1</nowiki>" 结果发现: /_media/logo.png 返回: HTTP/2 404 cf-cache-status: HIT 而: /lib/exe/fetch.php?media=logo.png 返回: HTTP/2 200 content-type: image/png 这说明源站和 DokuWiki 本身已经正常,真正的问题是:'''Cloudflare 缓存了之前的 404 页面。''' == 六、最终解决:清理 Cloudflare 缓存 == 进入 Cloudflare 后台: 缓存 → 配置 → 清除所有内容 清理后再次测试: curl -I "<nowiki>https://www.example.com/_media/logo.png</nowiki>" 返回变成: HTTP/2 200 content-type: image/png 此时 Logo 和缩略图也恢复正常。 ---- == 七、最终推荐配置片段 == 下面是最终比较稳定的 DokuWiki Nginx 伪静态配置片段: ''# 禁止访问敏感文件和目录'' location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md|data|conf|bin|inc|vendor) { return 404; } ''# SSL 证书验证目录'' location ^~ /.well-known/ { allow all; } ''# DokuWiki 媒体文件'' location ^~ /_media/ { rewrite ^/_media/(.*)$ /lib/exe/fetch.php?media=$1 last; } location ^~ /_detail/ { rewrite ^/_detail/(.*)$ /lib/exe/detail.php?media=$1 last; } location ^~ /_export/ { rewrite ^/_export/([^/]+)/(.*)$ /doku.php?do=export_$1&id=$2 last; } ''# DokuWiki 页面 URL 重写'' location / { try_files $uri $uri/ @dokuwiki; } location @dokuwiki { rewrite ^/(.*) /doku.php?id=$1&$args last; } ''# 静态图片缓存'' location ~* \.(gif|jpg|jpeg|png|bmp|swf|webp|svg|ico)$ { expires 30d; error_log /dev/null; access_log off; } ''# JS/CSS 缓存'' location ~* \.(js|css)$ { expires 12h; error_log /dev/null; access_log off; } 修改完成后检查配置并重载 Nginx: ---- == 八、DokuWiki 后台配置 == DokuWiki 后台还需要开启 <abbr>URL</abbr> 重写。 进入:管理 → 配置设置 → 高级设置 设置: 使用更整洁的URL<code>userewrite</code> 为<code>.htaccess</code> 启用在 <abbr>URL</abbr> 中使用斜杠作为命名空间的分隔符<code>useslash</code> ---- == 九、排查经验总结 == 这次问题主要分为三个阶段: 第一,页面 <abbr>URL</abbr> 重写正常,但媒体文件 404。 原因是 <code>/_media/*.png</code> 被 Nginx 的图片缓存 location 提前匹配,导致 Nginx 直接去文件系统寻找 <code>/_media/</code> 目录。 解决方法是给 <code>/_media/</code> 单独写: location ^~ /_media/ 并放在图片缓存规则之前。 第二,媒体文件直接访问恢复,但 Logo 和缩略图仍然异常。 这时需要用 <code>curl -I</code> 分别测试: /_media/logo.png /lib/exe/fetch.php?media=logo.png 如果 <code>fetch.php</code> 能返回 200,说明 DokuWiki 正常,问题不在 PHP 层。 第三,发现 Cloudflare 返回的是旧的 404 缓存。 判断依据是响应头里出现: cf-cache-status: HIT age: xxxx HTTP/2 404 说明请求甚至没有回到源站,而是 Cloudflare 直接返回了缓存结果。 最终清理 Cloudflare 缓存后,问题全部解决。 ---- == 十、结论 == DokuWiki 配置 <abbr>URL</abbr> 重写时,媒体文件无法显示并不一定是 DokuWiki 本身的问题,常见原因有: Nginx location 匹配顺序错误 静态资源缓存规则截走了 /_media/ 请求 Cloudflare 缓存了旧的 404 DokuWiki 页面缓存或缩略图缓存未刷新 排查时不要只看浏览器页面显示效果,最好用:<code>curl -I</code> 分别检查: /_media/xxx.png /lib/exe/fetch.php?media=xxx.png 这样可以快速判断问题到底出在: Nginx 重写 DokuWiki PHP 处理 Cloudflare 缓存 浏览器缓存 这次最终的关键点在于 # Nginx 使用 ^~ /_media/ 防止媒体请求被静态图片规则截走 # Cloudflare 清理旧的 404 缓存 完成这两步后,DokuWiki 的 <abbr>URL</abbr> 重写、媒体文件、Logo 和缩略图都恢复正常。 [[分类:技术博客]] [[分类:Dokuwiki]] [[分类:Nginx]]
返回
Dokuwiki URL重写
。
导航菜单
个人工具
创建账号
登录
命名空间
页面
讨论
大陆简体
查看
阅读
查看源代码
查看历史
更多
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
特殊页面
友情链接
狗窝 - 我的博客
小城的问候
工具
链入页面
相关更改
页面信息