我正在將舊網站連結遷移到新網站,它將使用相同的網域
這是一些舊連結。
舊連結 | 新連結 |
---|---|
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
in也p=catalog&action=viewimages
沒有使用,但是當我cat_id
從規則中刪除 時,p=catalog&action=viewimages&pid=10
總是重定向到p=catalog&action=viewimages&pid=1
,所以我不得不將cat_id
.
如果有人有更好的想法來處理查詢參數的動態順序,請隨時發布作為答案。如果有效,我會將其標記為已接受。
編輯:有關動態訂單查詢參數和更清晰的 if,請參閱伊凡·沙茨基的回答