Làm cách nào để xóa dấu gạch chéo khỏi URL bằng .htaccess?


8

Tình huống

Trên toàn bộ tên miền, chúng tôi muốn các URL ẩn phần mở rộng tệpxóa dấu gạch chéo , độc lập với chính tên miền (như trong, hoạt động trên bất kỳ tên miền nào).

Mẫu cấu trúc thư mục của chúng tôi

Chúng tôi không sử dụng các tệp chỉ mục. * Ngoại trừ trang chủ.

  • /
    • /index.php
    • /account.php
    • /tài khoản
      • /subcrip.php
    • /login.php
    • /đăng nhập
      • /reset-password.php

Mục đích

Một số ví dụ về cách các tệp này có thể được yêu cầu và cách chúng nhìn trong trình duyệt:

  • /index.php-> mydomain.com(nghĩa đen chỉ là tên miền trần).

  • /account.phphoặc /account/hoặc /account->mydomain.com/account

  • /account/subscriptions.phphoặc /account/subscriptions/hoặc /account/subscriptions->mydomain.com/account/subscriptions

Như bạn có thể thấy, có một số cách để truy cập mỗi trang web, nhưng cho dù bạn sử dụng cách nào trong 2 hoặc 3 cách để đến đó, nó chỉ hiển thị một URL ưa thích trong trình duyệt.

Câu hỏi

Làm thế nào điều này được thực hiện với .htaccess bằng mod_rewrite?

Tôi đã đập đầu vào tường cố gắng tìm ra điều này, nhưng nói chung, dòng chảy viết lại dường như là như thế này:

  1. Chuyển hướng ngoài 301 ( mydomain.com/account/-> mydomain.com/account)
  2. Nối thêm nội bộ .php ( mydomain.com/account-> mydomain.com/account.php)

Tôi đã làm việc này cả ngày, đọc hàng ngàn dòng tài liệu và cấu hình văn bản, và đã thử vài chục lần ... Tôi nghĩ rằng nhiều bộ não hơn về điều này sẽ giúp ích rất nhiều.

CẬP NHẬT

Chúng tôi tìm thấy một câu trả lời cho câu hỏi của chúng tôi (xem bên dưới).


Làm thế nào bạn phân biệt giữa tài khoản.php và tài khoản / thư mục? Đó là những gì dấu gạch chéo dành cho.
Kevin C.

Câu hỏi hay. Họ là những điều tương tự. Thư mục "tài khoản" viết lại thành "account.php". (Bạn sẽ thường tìm thấy cấu trúc này trong các dự án web của Visual Studio.)
Matt

Huh? Tôi xin lỗi, điều đó không có ý nghĩa với tôi. Nếu có tệp /account.php và tệp /account/index.php (thường được truy cập đơn giản bằng / account /), làm thế nào để bạn phân biệt giữa hai? Trên một hệ thống tập tin, chúng không giống nhau. Nếu bạn đang bootstrapping mọi thứ thông qua một thư mục index.php, giống như các khung công tác PHP, thì có lẽ điều đó có ý nghĩa. Đó có phải là ý bạn không?
Kevin C.

Xin lỗi, tôi nên đã rõ ràng hơn. Chúng tôi sẽ không sử dụng các tệp chỉ mục (ngoại trừ trang chủ; nhưng đừng lo lắng về điều đó cho câu hỏi này). Tất cả các tên tệp được mô tả nội dung của chúng. Điều này có nghĩa là, ví dụ, điều đó /account/sẽ viết lại /accountvà thực sự cung cấp /account.php, không /account/index.php .
Matt

Câu trả lời:


8

Cảm ơn bạn đã dành thời gian để xem xét câu hỏi, nhưng chúng tôi dường như đã tìm ra nó:

Options -Multiviews -Indexes +FollowSymLinks
RewriteEngine On
RewriteBase /
DirectorySlash Off

# remove trailing slash
RewriteRule ^(.*)\/(\?.*)?$ $1$2 [R=301,L]

# rewrite /dir/file?query to /dir/file.php?query
RewriteRule ^([\w\/-]+)(\?.*)?$ $1.php$2 [L,T=application/x-httpd-php]

Chúng ta phải tắt Multiview và Index để động cơ không bị nhầm lẫn và thay vào đó cố gắng tham chiếu bất kỳ index.*tệp nào hoặc hiển thị danh sách thư mục (còn gọi một cách nhầm lẫn là "chỉ mục" với Apache ...) khi thư mục xuất hiện được yêu cầu.

Chuyển hướng đầu tiên rõ ràng ( R=301) loại bỏ dấu gạch chéo và cái thứ hai bên trong viết lại nó vào tệp PHP (hoặc HTML, v.v.) trong tay.

Tệp .htaccess này cũng hỗ trợ các chuỗi truy vấn.

Cập nhật Như đã lưu ý trong các nhận xét bên dưới sớm hơn nhiều, chúng tôi đã chuyển sang nginx và đây là tất cả tệp conf của chúng tôi có liên quan đến việc viết lại URL (từ hộp dev của tôi):

location = / {
    index index.html;
}

try_files $uri $uri.html =404;

Chúng tôi cũng đã chuyển từ PHP sang HTML đơn giản, nhưng thay đổi các phần mở rộng ở trên hầu như không tạo ra sự khác biệt, nếu có.


Nhìn nhận lại, chúng tôi đã chuyển sang nginx và toàn bộ nhiệm vụ này cực kỳ dễ dàng ...
Matt

Điểm nhỏ, nhưng bạn không cần phải thoát dấu gạch chéo ( /) trong regex, vì nó không có ý nghĩa đặc biệt. \/giống như '/'.
MrWhite

@ w3d Điểm tốt. Đó là một thói quen từ regex'ing Javascript của tôi.
Matt

0

Tại sao bạn muốn chuyển hướng / tài khoản đến /account.php? Trên thực tế, trang / tài khoản chỉ tồn tại với đàm phán Nội dung . Nếu bạn không muốn nó, chỉ cần vô hiệu hóa lệnh.

Về hai quy tắc của bạn, tôi nghĩ nó đơn giản:

RewriteRule ^/account/$ /account
RewriteRule ^/account$ /account.php [R,L]

Nó chưa được kiểm tra, tuy nhiên. Bạn cũng có thể thêm [R,L]vào dòng đầu tiên, trong trường hợp này, trình duyệt sẽ thực hiện thêm một lần chuyển hướng.


1
Về lý thuyết, đó là ý tưởng chung (ngoại trừ chúng tôi không muốn hiển thị .php trong trình duyệt), nhưng điều đó chỉ hoạt động với tài khoản.php. Chúng tôi hy vọng cho một giải pháp chung hoạt động trên toàn trang web. Sử dụng refiddle để kiểm tra regex của chúng tôi, chúng tôi biết rằng regex giống như ^(.*)/$chỉ ra các URL có dấu gạch chéo, nhưng điều đó dường như chỉ có hiệu lực trong các thư mục cấp cao nhất, chứ không phải thư mục con. (Yêu cầu thư mục con viết lại với đường dẫn máy chủ đầy đủ trong URL và hiển thị nó trong trình duyệt vì một số lý do.) Chúng tôi cũng chắc chắn rằng ^(.*)[^/]$chỉ ra một URL mà không có dấu gạch chéo.
Matt

0

Nếu bạn muốn một cách linh hoạt và đơn giản để định tuyến các yêu cầu URL cho trang web hoặc ứng dụng của bạn, tôi sẽ đề xuất một khung vi mô PHP. Bạn không chỉ có toàn quyền kiểm soát định tuyến URL của mình mà còn cung cấp các lợi ích khác nữa.

Tôi đã sử dụng Slim Framework trước đây, kết hợp với Thành phần tạo khuôn Symfony với kết quả tuyệt vời. Nếu tôi làm điều đó một lần nữa, có lẽ tôi sẽ chỉ sử dụng khung Silex Micro , vì đó cũng là một phần của Thành phần Symfony.


Chúng tôi đã nghĩ về một cái gì đó như thế này (cảm ơn các liên kết), nhưng phiên bản phát triển của trang web của chúng tôi là do PHP cung cấp và trang web sản xuất được triển khai là tĩnh 100% (không có PHP). Tệp .htaccess này sẽ được xem trước trang web sản xuất được triển khai.
Matt

Sẽ rất dễ dàng để nhanh chóng tạo một trang web tĩnh dựa trên các khung vi mô này. Dự án mà tôi đã sử dụng chúng chủ yếu là nội dung tĩnh, chỉ với một đoạn PHP được sử dụng để khởi động trang web bằng cách sử dụng khung vi mô. Tùy thuộc vào kích thước của trang web, chuyển đổi nó sang sử dụng khung vi mô có thể nhanh hơn so với đập đầu bạn vào .htaccess cả ngày.
Kevin C.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.