我正在将旧网站链接迁移到新网站,它将使用相同的域名
这里有一些旧链接。
旧链接 | 新链接 |
---|---|
http://example.com/?p=contact | /接触 |
http://example.com/?p=static&id=career | /职业 |
http://example.com/?p=static&id=about | /关于 |
http://example.com/?p=catalog&action=images&cat_id=1 | /产品类别/类别-slug-1 |
http://example.com/?p=catalog&action=images&cat_id=2 | /产品类别/类别-slug-2 |
http://example.com/?p=catalog&action=viewimages&pid=1&cat_id=1 | /产品/产品-slug-1 |
http://example.com/?p=catalog&action=viewimages&pid=2&cat_id=3 | /产品/产品-slug-2 |
新的商品页面的URL里没有id,所以我手动把它们全部列出来,一共只有5个分类,20个商品页面。
在我知道不支持嵌套 if 之前,我曾尝试过此方法。
location / {
if ($arg_p = contact) { return 301 /contact; }
if ($arg_p = static) {
if ($arg_id = career) { return 301 /career; }
# other static pages redirect to /about
return 301 /about;
}
if ($arg_p = catalog) {
if ($arg_action = images) {
if ($arg_cat_id = 1) { return 301 /product-category/category-slug-1; }
if ($arg_cat_id = 2) { return 301 /product-category/category-slug-2; }
# other unlisted categories should redirect to /product-categories
return 301 /product-categories;
}
if ($arg_action = viewimages) {
if ($arg_pid = 1) { return 301 /product/product-slug-1/; }
if ($arg_pid = 2) { return 301 /product/product-slug-2/; }
}
# other unlisted links defaults to /products
return 301 /products;
}
}
配置应该是什么?
答案1
你可以用几个链式map
块。这里有一个想法:
map $arg_p $url_p {
contact /contact;
static $url_id;
catalog $url_action;
# default value will be an empty string
}
map $arg_id $url_id {
career /career;
about /about;
# other static pages redirect to /about
default /about;
}
map $arg_action $url_action {
images $url_cat_id;
viewimages $url_pid;
# other unlisted actions defaults to /products
default /products;
}
map $arg_cat_id $url_cat_id {
1 /product-category/category-slug-1;
2 /product-category/category-slug-2;
# other unlisted categories should redirect to /product-categories
default /product-categories;
}
map $arg_pid $url_pid {
1 /product/product-slug-1;
2 /product/product-slug-2;
# other unlisted products defaults to /products
default /products;
}
server {
listen ...
server_name ...
...
if ($url_p) { # if '$url_p' variable is not an empty string
return 301 $url_p;
}
location / {
...
}
...
}
一些map
块可以缩短,例如,假设您有 3 个静态页面/career
和/clients
“默认”页面/about
、5 个类别和 45 个产品:
map $arg_id $url_id {
~^(career|clients)$ /$1;
default /about;
}
map $arg_cat_id $url_cat_id {
~^([1-5])$ /product-category/category-slug-$1;
default /product-categories;
}
map $arg_pid $url_pid {
~^([1-9]|[1-3]\d|4[0-5])$ /product/product-slug-$1;
default /products;
}
更新
OP 表示他无法使用map
指令,因为他无权访问完整的 nginx 配置,而只能server
阻止内容。虽然以前的解决方案更加优雅(并且在性能方面应该更有效),但仅使用块也可以实现相同的效果if
:
if ($arg_p = contact) { return 301 /contact; }
if ($arg_p = static) { set $page static_$arg_id; }
if ($page = static_career) { return 301 /career; }
if ($page) { return 301 /about; } # anything that is not 'career' redirected to '/about'
if ($arg_p = catalog) { set $action $arg_action; }
if ($action = images) { set $page category_$arg_cat_id; }
if ($page = category_1) { return 301 /product-category/category-a; }
if ($page = category_2) { return 301 /product-category/category-b; }
# ... other categories
if ($action = images) { return 301 /product-categories; } # unlisted category specified
if ($action = viewimages) { set $page product_$arg_pid; }
if ($page = product_1) { return 301 /product/product-a; }
if ($page = product_2) { return 301 /product/product-b; }
# ... other products
if ($action = viewimages) { return 301 /products; } # unlisted product specified
# if you want to process any unlisted action in some special way
# if ($action) { ... } # 'action' query argument neither 'images' nor 'viewimages'
此片段可放置在server
或location
上下文中。
答案2
我最终得到了这个解决方案。
location / {
if ($arg_p = contact) { return 301 /contact; }
if ($args ~ p=static&id=career) { return 301 /career; }
if ($arg_p = static) { return 301 /about; }
if ($args ~ p=catalog&action=images&cat_id=1) { return 301 /product-category/category-a; }
if ($args ~ p=catalog&action=images&cat_id=2) { return 301 /product-category/category-b; }
# and other cat_id
if ($args ~ p=catalog&action=viewimages&pid=1&cat_id=1) { return 301 /product/product-a; }
if ($args ~ p=catalog&action=viewimages&pid=2&cat_id=1) { return 301 /product/product-b; }
# and other pid
if ($arg_p = catalog) { return 301 /products; } #other p=catalog defaults to /products
try_files $uri $uri/ /index.php$is_args$args;
}
它可以工作,但是它无法处理查询参数顺序未写在下面的情况,例如/?id=career&p=static
(id 和 p 被切换)
另外,cat_id
中p=catalog&action=viewimages
未使用,但是当我cat_id
从规则中删除时,p=catalog&action=viewimages&pid=10
总是重定向到p=catalog&action=viewimages&pid=1
,所以我不得不把cat_id
。
如果有人有更好的想法来处理查询参数的动态顺序,请随意发布答案。如果它有效,我会将其标记为已接受。
编辑:对于动态顺序查询参数和更清晰的 if,请参阅Ivan Shatsky 的回答