htacces vấn đề 2 biến

Nov 26 2020

TRƯỚC KHI tôi cài đặt SSL, mọi thứ vẫn hoạt động hoàn hảo !! Đây là mã tôi có trong tệp .htaccess máy chủ web gốc của mình:

Options +MultiViews
RewriteEngine On
RewriteCond %{HTTP_HOST} andrea\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://andrea.com/$1 [R,L]

RewriteCond %{DOCUMENT_ROOT}/$1.php -f RewriteRule (.*) $1.php [L]

Nó hoạt động và nó làm chính xác những gì tôi muốn nó làm. Vì vậy, nếu tôi đi đến ví dụ:

www.andrea.com/account

nó truy cập "www.andrea.com/account.php". Đó là những gì tôi muốn. Tuy nhiên, tôi có một thư mục trong gốc được gọi là "sản phẩm". Có một tệp ".htaccess" khác trong thư mục đó và tôi không biết phải thay đổi tệp nào trong số 2 tệp này để làm cho điều sau đây hoạt động.

Khi bạn truy cập url này: http: ____ / products / view / Hello / Goodbye

Tôi muốn nó truy cập "view.php" trong thư mục 'products' và trong tệp php đó, tôi có thể thực hiện điều này:

$id = $_GET["id"];    //      This would have "Hello"
$cat = $_GET["cat"];    //   This would have "Goodbye"

Và điều này hoạt động tốt khi tôi sử dụng htaccess này trong thư mục "products":

RewriteEngine on
RewriteCond %{HTTP_HOST} !^$ RewriteCond %{HTTP_HOST} !^www\. [NC] RewriteCond %{HTTPS}s ^on(s)| RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^/]*)/?(.*)$ /products/view.php?id=$1&cat=$2

Vấn đề với mã này ở trên là, nếu tôi truy cập: http: ____ / products / Hello / Goodbye

Tôi muốn nó truy cập vào "index.php" trong thư mục "products". Nhưng thay vào đó, nó chuyển đến "view.php" !! Nó giống như mã htaccess ở trên buộc tất cả phải truy cập vào view.php (điều này chỉ nên được thực hiện nếu tôi có "view / ____" trong url. Tôi muốn url ở trên chuyển đến "index.php" trong "sản phẩm "và trong tệp đó, tôi có thể truy cập các biến ID và CAT.

Bất kỳ ý tưởng nào về những gì cần thay đổi trong tệp .htaccess của tôi? Xin lỗi, tôi đã dành hơn 2 giờ, tôi không hiểu một dòng ở cuối mã của mình nhưng nó không hoạt động: /

Trả lời

1 AmitVerma Nov 26 2020 at 11:35

Bạn có thể sử dụng các nguyên tắc sau để viết lại /products/Hello/Goodbyeđể /products/index.php.

RewriteRule ^Hello/GoodBye/?$ /product/index.php?id=hello&cat=Goodbye  [L,NC]

Đây là hoàn thành của bạn /product/.htaccess.

RewriteEngine on
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
#rewrite /products/Hello/GoodBye to /products/index.php
RewriteRule ^Hello/GoodBye/?$ /products/index.php?id=Hello&cat=Goodbye [L,NC] ################### RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^/]*)/?(.*)$ /products/view.php?id=$1&cat=$2
1 MrWhite Nov 27 2020 at 07:13
 Options +MultiViews

Trước hết, bạn nên tắt MultiView. Trong câu trả lời của tôi cho câu hỏi trước đó của bạn , đề xuất sử dụng MultiViews của tôi hoàn toàn là một phương pháp "thay thế" trong bối cảnh câu hỏi của bạn. Bạn không thể sử dụng cả hai phương pháp (mod_rewrite MultiViews) để làm việc với URL không có phần mở rộng. Và vì bây giờ bạn muốn làm nhiều thứ hơn và chuyển các tham số, MultiViews sẽ chỉ tạo ra xung đột. (MultiView có thể sẽ "thắng" và không có thông số nào được chuyển.)

Ngoài ra, bạn có cần cụ thể .htaccesstệp bổ sung trong /productsthư mục con không? Sẽ dễ dàng hơn (được cho là) ​​để có một .htaccesstệp duy nhất trong gốc tài liệu. Điều này sẽ tránh phải lặp lại chuyển hướng HTTP sang HTTPS (mặc dù bạn chưa thực sự bao gồm chuyển hướng HTTP sang HTTPS trong .htaccesstệp thư mục con ?).

# /products/.htaccess
RewriteRule ^([^/]*)/?(.*)$ /products/view.php?id=$1&cat=$2

Lệnh này phù hợp với cả hai view/Hello/Goodbye Hello/Goodbye , điều này giải thích tại sao mọi thứ đang được ghi vào view.phptập lệnh của bạn . Tuy nhiên, nó không thực sự làm những gì bạn nói - điều này thật khó hiểu. Nếu bạn yêu cầu /products/view/Hello/Goodbyethì nó sẽ viết lại yêu cầu /products/view.php?id=view&cat=Hello/Goodbye- đó không phải là ý định (trừ khi MutliViews được kích hoạt, trong trường hợp đó sẽ không có tham số nào được chuyển).

Bạn cần thực sự kiểm tra viewsđường dẫn URL được yêu cầu trước khi cố gắng viết lại views.php. Và nếu viewskhông có thì hãy viết lại để index.phpthay thế. Việc "phân nhánh có điều kiện" này có thể đạt được bằng cách sắp xếp các chỉ thị theo thứ tự của các quy tắc "cụ thể hơn" trước.

Ví dụ, trong .htaccesstệp gốc của bạn, hãy thử cách sau. (Và xóa /products/.htaccesshoàn toàn tệp.)

# Ensure that MultiViews is disabled
Options -MultiViews

RewriteEngine On

# HTTP to HTTPS canonical redirect
RewriteCond %{HTTP_HOST} example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule (.*) https://example.com/$1 [R=301,L]

# Abort early if the request already maps to (or looks like) a file or directory
RewriteCond %{REQUEST_URI} \.\w{2,4}$ [OR] RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] # 1. Rewrite "/products/view/<id>/<cat>" to "/products/view.php?id=<id>&cat=<cat> RewriteRule ^(products/view)/([^/]*)/?(.*) $1.php?id=$2&cat=$3 [L]

# 2. Rewrite "/products/<id>/<cat>" to "/products/index.php?id=<id>&cat=<cat>
RewriteRule ^(products)/([^/]*)/?(.*) $1/index.php?id=$2&cat=$3 [L] # 3. Extensionless URLs for other requests RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.*) $1.php [L]

Thứ tự của 3 quy tắc trên là quan trọng. Quy tắc cụ thể nhất là đầu tiên. Bao gồm Lcờ để ngăn việc xử lý thêm (không cần thiết).

Lưu ý rằng, theo chỉ thị ban đầu của bạn, đối với yêu cầu của biểu mẫu /products/view/Hello/Goodbye(hoặc /products/Hello/Goodbye), Hello/Goodbyephần này hoàn toàn là tùy chọn và đương nhiên sẽ dẫn đến các tham số idcatURL được đặt nhưng trống.

Ngoài ra, theo chỉ thị ban đầu của bạn, một yêu cầu của biểu mẫu /products/view/Hello/Goodbye/foo/bar/bazsẽ dẫn đến cattham số URL được đặt thành Goodbye/foo/bar/baz(bất kỳ thứ gì theo sau phân đoạn đường dẫn ban đầu).

Bạn không nhất thiết phải kiểm tra xem một yêu cầu có ánh xạ tới một tệp hoặc thư mục (tương đối đắt tiền ) nếu bạn làm cho regex của mình cụ thể hơn và chỉ khớp với những gì bạn cần khớp. Ví dụ: regex của bạn /([^/]*)/?(.*)hiện đang khớp với khá nhiều thứ . Nhưng nếu biến <id>và của bạn <cat>chỉ có thể bao gồm các chữ cái thường (ví dụ) thì điều này có thể tránh được sự cần thiết của việc kiểm tra hệ thống tệp.

Các lưu ý khác:

  • Bạn có cần kiểm tra tên máy chủ trong chuyển hướng HTTP sang HTTPS không? Bạn có lưu trữ nhiều miền không? Nếu không, điều kiện kiểm tra HTTP_HOSTbiến máy chủ là không bắt buộc.