Ví dụ về cấu trúc tệp hiện tại:
example.com/foo.php
example.com/bar.html
example.com/directory/
example.com/directory/foo.php
example.com/directory/bar.html
example.com/cgi-bin/directory/foo.cgi*
Tôi muốn xóa các phần mở rộng HTML, PHP và CGI khỏi, và sau đó buộc dấu gạch chéo ở cuối URL. Vì vậy, nó có thể trông như thế này:
example.com/foo/
example.com/bar/
example.com/directory/
example.com/directory/foo/
example.com/directory/bar/
example.com/cgi-bin/directory/foo/
Tôi rất thất vọng vì tôi đã tìm kiếm 17 giờ liên tục để tìm giải pháp và đã truy cập hơn vài trăm trang trên các blog và diễn đàn khác nhau. Tôi không nói đùa. Vì vậy, tôi nghĩ rằng tôi đã thực hiện nghiên cứu của tôi.
Đây là mã nằm trong tệp .htaccess của tôi ngay bây giờ:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(([^/]+/)*[^./]+)/$ $1.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]|/)$
RewriteRule (.*)$ /$1/ [R=301,L]
Như bạn có thể thấy, mã này chỉ loại bỏ .html (và tôi không hài lòng lắm với nó vì tôi nghĩ nó có thể được thực hiện đơn giản hơn rất nhiều). Tôi có thể xóa phần mở rộng khỏi các tệp PHP khi tôi đổi tên chúng thành .html thông qua .htaccess, nhưng đó không phải là điều tôi muốn. Tôi muốn loại bỏ nó thẳng. Đây là điều đầu tiên tôi không biết làm.
Điều thứ hai thực sự rất khó chịu. Tệp .htaccess của tôi với mã ở trên, thêm .html/
vào mỗi chuỗi được nhập sau example.com/directory/foo/
. Vì vậy, nếu tôi nhập example.com/directory/foo/bar
(rõ ràng /bar
không tồn tại vì foo
là một tệp), thay vì chỉ hiển thị thông báo mà trang đó không được tìm thấy, nó sẽ chuyển đổi thành example.com/directory/foo/bar.html/
, sau đó tìm kiếm tệp trong vài giây và sau đó hiển thị thông báo không tìm thấy. Điều này, tất nhiên, là hành vi xấu.
Vì vậy, một lần nữa, tôi cần mã trong .htaccess để làm những việc sau:
- Xóa phần mở rộng .html
- Xóa phần mở rộng .php
- Xóa phần mở rộng .cgi
- Buộc dấu gạch chéo ở cuối URL
- Yêu cầu phải hành xử chính xác (không thêm dấu gạch chéo hoặc phần mở rộng vào chuỗi nếu tệp hoặc thư mục không tồn tại trên máy chủ)
- Mã phải đơn giản nhất có thể
@Kronbernkzion xuất sắc. Vấn đề duy nhất tôi gặp phải bây giờ là 404 dường như không hoạt động đúng và dẫn tôi đến một nơi thực sự thú vị, thậm chí tôi không thể sử dụng chuyển hướng 404 tuyệt đối.
ErrorDocument 404 http://www.google.com
Bạn đã đi qua điều này? Làm thế nào bạn vượt qua nó?
Ngoài việc viết lại 404, mã đầy đủ tôi đã sử dụng là:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} (.*)/$
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule (.*)/$ $1.html [L]
RewriteCond %{REQUEST_URI} (.*)/$
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*)/$ $1.php [L]
RewriteCond %{REQUEST_URI} (.*)/$
RewriteCond %{REQUEST_FILENAME}\.cgi -f
RewriteRule (.*)/$ $1.cgi [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f [OR]
RewriteCond %{REQUEST_FILENAME}\.php -f [OR]
RewriteCond %{REQUEST_FILENAME}\.cgi -f
RewriteRule .* %{REQUEST_FILENAME}/ [R=301,L]
</IfModule>
/foo.html
và /bar.php
, thì bạn sẽ có một quy tắc rõ ràng phù hợp /foo/
để /foo.html
và /bar/
để /bar.php
? Hoặc bạn có cần một mục chung chung phù hợp /foo/
với cả /foo.html
OR /foo.php
(tùy thuộc vào mục nào tồn tại) không?