从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
相关产品推荐
相关产品推荐

