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

从Drupal迁移至Jekyll后,Nginx无法重写带/?q=的旧URL问题

解决Nginx下Drupal旧URL(/?q=permalink)跳转Jekyll新链接的问题

我一眼就看出问题出在哪了——Nginx的rewrite规则默认是只匹配URI部分(也就是?前面的内容),完全不会管?后面的查询字符串!你写的^/\?q=(.*)$永远匹配不上,因为请求的URI其实是/,q=my-post-permalink是单独的查询参数,两者是分开处理的。

问题分析

看你日志里的这条核心记录:

2018/01/14 09:42:17 [notice] 5#5: 1 "^/?q=(.)$" does not match "/", client: 127.0.0.1, server: localhost, request: "GET /?q=my-post-permalink HTTP/1.1", host: "my.domain.net"

这就把问题说透了:Nginx在匹配rewrite规则时,只拿/这个URI去对比你的正则,自然匹配失败,然后就走了try_files规则,返回了首页,而不是你想要的跳转。

正确的配置方案

我们需要利用Nginx的$arg_q变量(这个变量会自动提取查询参数里的q值),结合if指令来判断并跳转。修改你的default.conf如下:

location / {
    root /usr/share/nginx/html;
    index index.html index.htm;

    # 匹配带有?q=参数的旧链接,执行301永久跳转
    if ($arg_q) {
        rewrite ^/$ /$arg_q permanent;
    }

    try_files $uri $uri/ $uri.html =404;
}

细节说明

  • $arg_q:Nginx内置变量,直接提取查询字符串中q参数的值,比如请求/?q=my-post-permalink时,$arg_q的值就是my-post-permalink。
  • permanent:表示发送301永久重定向,这对SEO非常友好,告诉搜索引擎旧链接已经永久迁移到新地址。如果只是临时测试,可以换成redirect(302临时重定向)。
  • 这个if判断只会在q参数存在时触发,不会影响其他正常请求(比如你的/css/foundation.css这类静态资源请求)。

验证方法

修改配置后,执行nginx -s reload重新加载配置,然后访问http://my.domain.net/?q=my-post-permalink,应该会自动跳转到http://my.domain.net/my-post-permalink,同时日志里会显示301的跳转记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:29:41