Apache mod_rewrite
Những gì bạn đang tìm kiếm là mod_rewrite ,
Mô tả: Cung cấp công cụ viết lại dựa trên quy tắc để viết lại các URL được yêu cầu một cách nhanh chóng.
Nói chung, mod_rewrite
hoạt động bằng cách đối sánh tài liệu được yêu cầu với các biểu thức chính quy được chỉ định, sau đó thực hiện ghi lại URL bên trong (trong quy trình apache) hoặc bên ngoài (trong trình duyệt máy khách). Các bản viết lại này có thể đơn giản như dịch nội bộ example.com/foo thành một yêu cầu cho example.com/foo/bar.
Tài liệu Apache bao gồm một mod_rewrite
hướng dẫn và tôi nghĩ rằng một số điều bạn muốn làm đều có trong đó. Hướng dẫn mod_rewrite chi tiết .
Buộc www
tên miền phụ
Tôi muốn nó buộc "www" trước mỗi url, vì vậy nó không phải là domain.com mà là www.domain.com/page
Hướng dẫn viết lại bao gồm hướng dẫn cho việc này trong ví dụ Tên máy chủ hợp quy .
Xóa dấu gạch chéo (Phần 1)
Tôi muốn xóa tất cả các dấu gạch chéo ở cuối trang
Tôi không chắc tại sao bạn lại muốn làm điều này vì hướng dẫn viết lại bao gồm một ví dụ hoàn toàn ngược lại , tức là luôn bao gồm dấu gạch chéo ở cuối. Tài liệu gợi ý rằng việc loại bỏ dấu gạch chéo có khả năng gây ra sự cố lớn:
Vấn đề về dấu gạch chéo
Sự miêu tả:
Mọi quản trị viên web có thể hát một bài hát về vấn đề dấu gạch chéo trên các URL tham chiếu đến thư mục. Nếu chúng bị thiếu, máy chủ kết xuất lỗi, vì nếu bạn nói /~quux/foo
thay vì /~quux/foo/
thì máy chủ sẽ tìm kiếm tệp có tên foo. Và bởi vì tệp này là một thư mục mà nó phàn nàn. Trên thực tế, nó cố gắng tự sửa lỗi trong hầu hết các trường hợp, nhưng đôi khi cơ chế này cần được bạn mô phỏng. Ví dụ: sau khi bạn đã thực hiện nhiều thao tác ghi lại URL phức tạp thành tập lệnh CGI, v.v.
Có lẽ bạn có thể mở rộng lý do tại sao bạn luôn muốn xóa dấu gạch chéo?
Xóa .php
phần mở rộng
Tôi cần nó để xóa .php
Điều gần nhất để làm điều này mà tôi có thể nghĩ đến là viết lại nội bộ mọi tài liệu yêu cầu bằng phần mở rộng .php, tức là example.com/somepage thay vào đó được xử lý dưới dạng yêu cầu cho example.com/somepage.php. Lưu ý rằng tiếp tục theo cách này sẽ yêu cầu mỗi trang thực sự tồn tại dưới dạng somepage.php trên hệ thống tệp.
Với sự kết hợp phù hợp của các cụm từ thông dụng, điều này sẽ có thể thực hiện được ở một mức độ nào đó. Tuy nhiên, tôi có thể thấy trước một số vấn đề có thể xảy ra với các trang chỉ mục không được yêu cầu chính xác và không khớp các thư mục một cách chính xác.
Ví dụ: điều này sẽ viết lại chính xác example.com/test dưới dạng yêu cầu cho example.com/test.php:
RewriteEngine on
RewriteRule ^(.*)$ $1.php
Nhưng sẽ làm cho example.com không tải được vì không có example.com/.php
Tôi đoán rằng nếu bạn xóa tất cả các dấu gạch chéo, thì việc chọn một yêu cầu cho chỉ mục thư mục từ một yêu cầu cho một tên tệp trong thư mục mẹ sẽ trở nên gần như không thể. Làm cách nào để xác định yêu cầu cho thư mục 'foobar':
example.com/foobar
từ một yêu cầu cho một tệp có tên foobar (thực chất là foobar.php)
example.com/foobar
Có thể có nếu bạn sử dụng RewriteBase
chỉ thị. Nhưng nếu bạn làm điều đó thì vấn đề này trở nên phức tạp hơn vì bạn sẽ yêu cầu RewriteCond
các lệnh để thực hiện kiểm tra mức hệ thống tệp nếu yêu cầu ánh xạ tới một thư mục hoặc một tệp.
Điều đó nói rằng, nếu bạn loại bỏ yêu cầu xóa tất cả các dấu gạch chéo và thay vào đó, buộc thêm các dấu gạch chéo vào, thì vấn đề "không có phần mở rộng .php" sẽ hợp lý hơn một chút.
# Turn on the rewrite engine
RewriteEngine on
# If the request doesn't end in .php (Case insensitive) continue processing rules
RewriteCond %{REQUEST_URI} !\.php$ [NC]
# If the request doesn't end in a slash continue processing the rules
RewriteCond %{REQUEST_URI} [^/]$
# Rewrite the request with a .php extension. L means this is the 'Last' rule
RewriteRule ^(.*)$ $1.php [L]
Điều này vẫn chưa hoàn hảo - mọi yêu cầu cho tệp vẫn có .php được thêm vào yêu cầu trong nội bộ. Yêu cầu 'hi.txt' sẽ đưa thông tin này vào nhật ký lỗi của bạn:
[Tue Oct 26 18:12:52 2010] [error] [client 71.61.190.56] script '/var/www/test.peopleareducks.com/rewrite/hi.txt.php' not found or unable to stat
Nhưng có một tùy chọn khác, đặt DefaultType
và các lệnh DirectoryIndex
như thế này:
DefaultType application/x-httpd-php
DirectoryIndex index.php index.html
Cập nhật 2013-11-14 - Đã sửa đoạn mã trên để kết hợp quan sát của nicorellius
Bây giờ các yêu cầu cho hi.txt (và bất kỳ thứ gì khác) đã thành công, các yêu cầu tới example.com/test sẽ trả về phiên bản đã xử lý của test.php và các tệp index.php sẽ hoạt động trở lại.
Tôi phải cung cấp tín dụng cho giải pháp này vì tôi đã tìm thấy nó Michael J. Radwins Blog bằng cách tìm kiếm trên Google cho php không có apache mở rộng .
Xóa dấu gạch chéo ở cuối
Một số tìm kiếm apache remove trailing slashes
đã đưa tôi đến một số trang Tối ưu hóa Công cụ Tìm kiếm. Rõ ràng một số Hệ thống quản lý nội dung (trong trường hợp này là Drupal) sẽ cung cấp nội dung có và không có dấu gạch chéo trong URls, điều này trong thế giới SEO sẽ khiến trang web của bạn bị phạt nội dung trùng lặp. Nguồn
Giải pháp có vẻ khá đơn giản, bằng cách sử dụng mod_rewrite
chúng tôi viết lại với điều kiện tài nguyên được yêu cầu kết thúc bằng a /
và viết lại URL bằng cách gửi lại 301 Permanent Redirect
tiêu đề HTTP.
Đây là ví dụ của anh ấy, giả sử miền của bạn là blamcast.net và cho phép yêu cầu có tiền tố tùy chọn www.
.
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?blamcast\.net$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
Bây giờ chúng ta đang đến một nơi nào đó. Hãy tập hợp tất cả lại với nhau và xem nó trông như thế nào.
Bắt buộc www.
, không .php
và không có dấu gạch chéo
Điều này giả sử miền là foobar.com và nó đang chạy trên cổng tiêu chuẩn 80.
# Process all files as PHP by default
DefaultType application/x-httpd-php
# Fix sub-directory requests by allowing 'index' as a DirectoryIndex value
DirectoryIndex index index.html
# Force the domain to load with the www subdomain prefix
# If the request doesn't start with www...
RewriteCond %{HTTP_HOST} !^www\.foobar\.com [NC]
# And the site name isn't empty
RewriteCond %{HTTP_HOST} !^$
# Finally rewrite the request: end of rules, don't escape the output, and force a 301 redirect
RewriteRule ^/?(.*) http://www.foobar.com/$1 [L,R,NE]
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?foobar\.com$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
Cờ 'R' được mô tả trong phần RewriteRule
chỉ thị. Đoạn trích:
redirect|R [=code]
(buộc chuyển hướng) Thay thế tiền tố bằng
http://thishost[:thisport]/
(làm cho URL mới trở thành URI) để buộc chuyển hướng bên ngoài. Nếu không có mã nào được cung cấp, phản hồi HTTP 302 ( MOVED TEMPORARILY ) sẽ được trả về.
Ghi chú cuối cùng
Tôi không thể làm cho việc loại bỏ dấu gạch chéo hoạt động thành công. Chuyển hướng đã kết thúc với tôi vòng lặp chuyển hướng vô hạn. Sau khi đọc kỹ hơn giải pháp ban đầu, tôi có ấn tượng rằng ví dụ trên phù hợp với họ vì cách cài đặt Drupal của họ được cấu hình. Anh ấy đề cập cụ thể:
Trên một trang web Drupal bình thường, với các URL sạch được bật, hai địa chỉ này về cơ bản có thể hoán đổi cho nhau
Liên quan đến các URL kết thúc bằng và không có dấu gạch chéo. Hơn nữa,
Drupal sử dụng một tệp được gọi .htaccess
để cho máy chủ web của bạn biết cách xử lý URL. Đây là cùng một tệp cho phép tạo URL sạch của Drupal. Bằng cách thêm một lệnh chuyển hướng đơn giản vào đầu
.htaccess
tệp, bạn có thể buộc máy chủ tự động xóa bất kỳ dấu gạch chéo nào.