Điểm:0

Nginx chuyển hướng dựa trên chuỗi truy vấn

lá cờ in

Tôi đang di chuyển các liên kết trang web cũ sang trang web mới, nó sẽ sử dụng cùng một tên miền

Đây là một số liên kết cũ.

Liên kết cũ Liên kết mới
http://example.com/?p=contact /liên hệ
http://example.com/?p=static&id=career /nghề nghiệp
http://example.com/?p=static&id=about /xung quanh
http://example.com/?p=catalog&action=images&cat_id=1 /product-category/category-slug-1
http://example.com/?p=catalog&action=images&cat_id=2 /product-category/category-slug-2
http://example.com/?p=catalog&action=viewimages&pid=1&cat_id=1 /product/product-slug-1
http://example.com/?p=catalog&action=viewimages&pid=2&cat_id=3 /product/product-slug-2

Trang sản phẩm mới không có id trong URL, vì vậy tôi liệt kê tất cả chúng theo cách thủ công và tổng cộng chúng chỉ có 5 danh mục và 20 trang sản phẩm.

Đây là những gì tôi đã thử trước khi tôi biết rằng if lồng nhau không được hỗ trợ.

địa điểm / {
    nếu ($arg_p = liên hệ) { return 301 /liên hệ; }
    nếu ($arg_p = tĩnh) { 
        if ($arg_id = sự nghiệp) { return 301 /sự nghiệp; }
        # các trang tĩnh khác chuyển hướng đến /about
        trở về 301 /về;
    }

    nếu ($arg_p = danh mục) {
        nếu ($arg_action = hình ảnh) {
            if ($arg_cat_id = 1) { return 301 /product-category/category-slug-1; }
            if ($arg_cat_id = 2) { return 301 /product-category/category-slug-2; }
            # danh mục không công khai khác sẽ chuyển hướng đến /product-categories
            trả lại 301 /danh mục sản phẩm;
        }
        nếu ($arg_action = viewimages) {
            if ($arg_pid = 1) { return 301 /product/product-slug-1/; }
            if ($arg_pid = 2) { return 301 /product/product-slug-2/; }
        }
        # các liên kết không công khai khác mặc định là /products
        trả lại 301 /sản phẩm;
    }
}

Cấu hình nên là gì?

Điểm:2
lá cờ gr

Bạn có thể làm điều đó với một số chuỗi bản đồ khối. Đây là một ý tưởng:

bản đồ $arg_p $url_p {
    liên hệ /liên hệ;
    tĩnh $ url_id;
    danh mục $url_action;
    # giá trị mặc định sẽ là một chuỗi rỗng
}

bản đồ $arg_id $url_id {
    sự nghiệp/nghề nghiệp;
    về/về;
    # các trang tĩnh khác chuyển hướng đến /about
    mặc định/về;
}

bản đồ $arg_action $url_action {
    hình ảnh $url_cat_id;
    lượt xem hình ảnh $url_pid;
    # hành động không công khai khác mặc định là /products
    mặc định/sản phẩm;
}

bản đồ $arg_cat_id $url_cat_id {
    1 /product-category/category-slug-1;
    2 /product-category/category-slug-2;
    # danh mục không công khai khác sẽ chuyển hướng đến /product-categories
    mặc định/danh mục sản phẩm;
}

bản đồ $arg_pid $url_pid {
    1 /product/product-slug-1;
    2 /product/product-slug-2;
    # sản phẩm chưa niêm yết khác mặc định là /products
    mặc định/sản phẩm;
}

người phục vụ {
    nghe ...
    tên máy chủ ...
    ...
    biến if ($url_p) { # if '$url_p' không phải là chuỗi rỗng
        trả lại 301 $ url_p;
    }
    địa điểm / {
        ...
    }
    ...
}

Một số bản đồ các khối có thể được rút ngắn, ví dụ: giả sử bạn có 3 trang tĩnh /nghề nghiệp, /khách hàng và trang "mặc định" /xung quanh, 5 danh mục và 45 sản phẩm:

bản đồ $arg_id $url_id {
    ~^(nghề nghiệp|khách hàng)$ /$1;
    mặc định/về;
}

bản đồ $arg_cat_id $url_cat_id {
    ~^([1-5])$ /product-category/category-slug-$1;
    mặc định/danh mục sản phẩm;
}

bản đồ $arg_pid $url_pid {
    ~^([1-9]|[1-3]\d|4[0-5])$ /product/product-slug-$1;
    mặc định/sản phẩm;
}

Cập nhật

OP nói rằng anh ấy không thể sử dụng bản đồ chỉ thị vì anh ta không có quyền truy cập vào cấu hình nginx đầy đủ mà chỉ truy cập vào người phục vụ khối nội dung.Mặc dù giải pháp trước đó thanh lịch hơn nhiều (và sẽ hiệu quả hơn về mặt hiệu suất), nhưng có thể thực hiện tương tự chỉ bằng cách sử dụng nếu khối:

nếu ($arg_p = liên hệ) { return 301 /liên hệ; }

nếu ($arg_p = tĩnh) { đặt $trang tĩnh_$arg_id; }
if ($page = static_career) { return 301 /career; }
if ($page) { return 301 /about; } # bất kỳ thứ gì không phải là 'nghề nghiệp' được chuyển hướng đến '/about'

nếu ($arg_p = danh mục) { đặt $action $arg_action; }

if ($action = hình ảnh) { 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; }
#...các danh mục khác
if ($action = images) { return 301 /product-categories; } # danh mục chưa được chỉ định

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; }
# ... sản phẩm khác
if ($action = viewimages) { return 301 /products; } # sản phẩm chưa niêm yết đã chỉ định

# nếu bạn muốn xử lý bất kỳ hành động không công khai nào theo một cách đặc biệt nào đó
# if ($action) { ... } # đối số truy vấn 'hành động' không phải 'hình ảnh' hay 'viewimages'

Đoạn này có thể được đặt trong người phục vụ hoặc địa điểm bối cảnh.

lá cờ in
Tôi nhận được lệnh `nginx: [emerg] "map" không được phép ở đây`. Không thể sử dụng bản đồ bên trong khối `máy chủ`? Tôi không có quyền truy cập để sửa đổi nginx bên ngoài khối `server`.
lá cờ in
Tìm thấy những câu hỏi này https://stackoverflow.com/questions/27358804/, vì vậy tôi nghĩ rằng bản đồ không phải là một lựa chọn cho tôi. Có thể chỉ cần viết lại (regex cho thông số truy vấn cũ) (liên kết mới) không? Tôi không hiểu nhiều về regex.
lá cờ in
Đó là một mẹo hay để nối các tham số truy vấn và lưu trữ chúng dưới dạng một biến.
Điểm:1
lá cờ in

Tôi đã kết thúc với giải pháp này.

địa điểm / {
  nếu ($arg_p = liên hệ) { return 301 /liên hệ; }
  if ($args ~ p=static&id=career) { return 301 /career; }
  if ($arg_p = tĩnh) { trả về 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; }
  # và cat_id khác
  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; }
  # và pid khác
  if ($arg_p = danh mục) { return 301 /products; } #other p=catalog mặc định là /products
  try_files $uri $uri/ /index.php$is_args$args;
}

Nó đang hoạt động, nhưng nó không thể xử lý trường hợp khi thứ tự tham số truy vấn không được viết bên dưới, ví dụ: /?id=nghiệp&p=static (id và p được chuyển đổi xung quanh)

Cũng thế cat_id Trong p=catalog&action=viewimages không được sử dụng, nhưng khi tôi gỡ bỏ cat_id từ các quy tắc, p=catalog&action=viewimages&pid=10 luôn chuyển hướng đến p=catalog&action=viewimages&pid=1, vì vậy tôi đã phải đặt cat_id.

Nếu ai đó có ý tưởng tốt hơn để xử lý thứ tự động cho các tham số truy vấn, vui lòng đăng dưới dạng câu trả lời. Tôi sẽ đánh dấu nó là được chấp nhận nếu nó hoạt động.

CHỈNH SỬA: Đối với thông số truy vấn thứ tự động và nếu sạch hơn nhiều, hãy xem Câu trả lời của Ivan Shatsky

Ivan Shatsky avatar
lá cờ gr
Xem bản cập nhật cho câu trả lời của tôi.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.