Nó phụ thuộc vào nơi nào trong <VirtualHost>
container mà bạn đang đặt các chỉ thị này.
Nếu bạn đang sử dụng một <Directory>
thùng chứa (tức là một danh mục ngữ cảnh) và vô hiệu hóa .htaccess
ghi đè hoàn toàn (nếu không .htaccess
sẽ ghi đè lên <Directory>
container!) thì bạn có thể sao chép nguyên trạng các chỉ thị (giả sử <Directory>
vùng chứa tham chiếu cùng thư mục với .htaccess
tập tin đã làm).
Tuy nhiên, nếu bạn đang đặt các chỉ thị này trực tiếp bên trong <VirtualHost>
thùng chứa (bên ngoài một <Directory>
thùng chứa), tức là. trong một Máy chủ ảo ngữ cảnh, thì bạn cần thực hiện một số thay đổi. Điều này là do các lệnh được xử lý trước đó, trước khi yêu cầu được ánh xạ tới hệ thống tệp.
Trong các chỉ thị bạn đã đăng, chỉ cần có hai thay đổi:
trong một Máy chủ ảo bối cảnh, các REQUEST_FILENAME
biến máy chủ vẫn chưa được giải quyết thành một tên tập tin. Nó giống như REQUEST_URI
(tức là URL được yêu cầu). Vì vậy, kiểm tra hệ thống tệp của bạn sẽ luôn thất bại và điều kiện sẽ luôn thành công! Bạn cần phải sử dụng một cái nhìn phía trước. ví dụ. %{LA-U:REQUEST_FILENAME}
hoặc tự tạo tên tệp tuyệt đối. ví dụ. %{DOCUMENT_ROOT}%{REQUEST_URI}
. Ví dụ:
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
trong một Máy chủ ảo bối cảnh, đường dẫn URL phù hợp với viết lại quy tắc
mẫu là gốc họ hàng (bắt đầu bằng dấu gạch chéo). Trong khi ở .htaccess
nó liên quan đến thư mục chứa .htaccess
tệp - trừ tiền tố dấu gạch chéo. Vì vậy, quy tắc như đã viết sẽ dẫn đến dấu gạch chéo kép ở đầu đường dẫn URL, thay vào đó, quy tắc nên được viết lại như sau:
RewriteRule ^/(.*)$ /$1/ [R,L]
(Các NC
cờ không bắt buộc ở đây.)
Hoặc (tốt hơn) không sử dụng phản hồi ở đây và sử dụng REQUEST_URI
thay vào đó, biến máy chủ (sẽ hoạt động tự nhiên trong .htaccess
cũng). Ví dụ:
Quy tắc viết lại ^ %{REQUEST_URI}/ [R,L]
(Qua một bên: Đây có lẽ cũng là một chuyển hướng vĩnh viễn 301 (tức là. R=301
). Như hiện tại, điều này sẽ mặc định là chuyển hướng tạm thời 302. Nhưng chỉ thay đổi thành 301 - nếu đó là ý định - sau khi bạn đã xác nhận rằng nó hoạt động như dự kiến.)
Vì vậy, tóm lại, điều này sẽ trở thành:
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteCond %{REQUEST_URI} !^/application-module/(.*)$
RewriteCond %{REQUEST_URI} !(.*)json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/(.*)$ [NC]
RewriteRule ^/(.*)$ /$1/ [R,L]
Qua một bên:
Ở trên có thể được tối ưu hóa ngay lập tức một chút bằng cách di chuyển kiểm tra hệ thống tệp (tương đối đắt) đến điều kiện cuối cùng và di chuyển điều kiện, tình trạng, trạng thái kiểm tra xem yêu cầu chưa kết thúc bằng dấu gạch chéo đối với viết lại quy tắc
chỉ thị. Ngoài ra, các mẫu con regex (.*)
trong mỗi điều kiện không bắt buộc. Vì vậy, ở trên có thể được viết lại hiệu quả hơn:
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_URI} !^/application-module/
RewriteCond %{REQUEST_URI} !json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/ [NC]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule !/$ %{REQUEST_URI}/ [R,L]
Kiểm tra hệ thống tệp có thể bị xóa hoàn toàn nếu thay vào đó, bạn loại trừ các yêu cầu có chứa (trông giống như) phần mở rộng tệp, nhưng điều này có thể phụ thuộc vào cấu trúc tệp của bạn.
Các điều kiện, tình trạng, trạng thái kiểm tra đó !json$
có vẻ như nó thực sự nên được kiểm tra cho .json
phần mở rộng tập tin, tức là. !\.json$
. (Điều này liên quan đến nhận xét của tôi ở trên về việc loại trừ tất cả các các yêu cầu có "phần mở rộng tệp".)
đầu tiên điều kiện, tình trạng, trạng thái kiểm tra xem chuỗi truy vấn có trống không có vẻ hơi kỳ quặc (vì việc có chuỗi truy vấn hay không khi thêm dấu gạch chéo vào đường dẫn URL không thực sự quan trọng), nhưng tôi cho rằng đây phải là một yêu cầu cụ thể?