2010-03-26 35 views
5

Tôi đang sử dụng apache/mod_rewrite để viết lại URL nhưng tôi gặp sự cố với dấu cộng.Dấu hiệu Apache mod_rewrite% 2B và dấu cộng (+)

Với các nguyên tắc sau ..

RewriteRule ^/(.+[^/])/?$ http://localhost:8080/app/home?tag=$1 [P,L] 

Cả:

http://localhost/1+1 and http://localhost/1%2B2 

cuối lên như

uri=http://localhost:8080/app/home, args=tag=1+2 

Vì vậy, trong cả hai trường hợp ứng dụng dịch vào dấu cộng vào một không gian quá nó không thể phân biệt giữa không gian và dấu cộng nữa.

Nếu tôi sử dụng "B" cờ, sau đó trong cả hai trường hợp, các dấu hiệu + được quy đổi sang% 2B và ứng dụng kết thúc với cùng một vấn đề nhưng đảo ngược (cả không gian và dấu cộng là dấu cộng)

Có cách nào để có được apache để thoát đúng% 2B vào một dấu cộng và không phải là một không gian?

Tôi đã đọc điều gì đó về mod_security nhưng tôi không sử dụng điều đó vì vậy tôi không chắc liệu có một số cơ chế bảo mật khác gây ra điều này không?

Bất kỳ trợ giúp nào sẽ được đánh giá rất nhiều!

Trả lời

2

Không, điều này không hoàn toàn giống với câu hỏi được tham chiếu. Vấn đề ở đây đặc biệt là các dấu hiệu và câu trả lời cho Apache: mod_rewrite: Spcaes & Special Characters in URL not working không giải quyết vấn đề đó.

Ngoài ra còn có vấn đề với dấu gạch chéo, xem http://httpd.apache.org/docs/current/mod/core.html#allowencodedslashes (nhưng bạn cần truy cập vào cấu hình Apache để thực hiện việc này - .htaccess sẽ không thực hiện).

Thực tế, không thể không thể chỉ sử dụng quy tắc viết lại. Apache giải mã URL trước khi đưa nó qua viết lại, nhưng nó không hiểu dấu cộng: http://example.com/a+b.html sẽ không đưa ra một tập tin gọi là

"một b.html".

Dấu cộng được PHP giải mã vào mảng $ _GET (hoặc bất kỳ cơ chế ngôn ngữ có liên quan nào) cho chuỗi truy vấn, vì trình xử lý biểu mẫu trong trình duyệt đưa chúng vào. Vì vậy, Apache sẽ dịch% 2B sang + trước khi áp dụng viết lại, và để lại + chính nó một mình, có nghĩa là bạn không thể nói sự khác biệt.

Tất nhiên, người ta có thể cho rằng + được sử dụng làm không gian đơn giản là không hợp lệ trong các URL như vậy và chỉ nên sử dụng% 20. Tuy nhiên, nếu bạn không có quyền kiểm soát việc tạo ra chúng, bạn chắc chắn sẽ thấy chúng. Tuy nhiên, các trình duyệt sẽ không tạo chúng tự động.

Câu trả lời là DIY, và bằng nhiều cách đó là dễ dự đoán hơn và đơn giản hơn:.

RewriteRule * index.php [L]

Do đó tất cả mọi thứ biến thành index.php và có không cố gắng xây dựng chuỗi truy vấn. Nếu bạn muốn loại trừ các mẫu nhất định, ví dụ:những người bị gạch chéo, hoặc nơi một tập tin rõ ràng tồn tại, những sửa đổi rõ ràng sẽ được áp dụng. ví dụ. RewriteCond% {REQUEST_FILENAME} -f

Sau đó, trong index.php

$ uri = substr ($ _ MÁY CHỦ [ 'REQUEST_URI'], 1)!; // xóa dấu gạch chéo hàng đầu

$ qmpos = strpos ($ uri, '?'); // có dấu chấm hỏi, nếu có nơi

nếu ($ qmpos! == FALSE) {$ uri = substr ($ uri, 0, $ qmpos); } // chỉ bit trước q.m.

$ decoded = urldecode ($ uri); // giải mã phần trước URL

nếu (! empty ($ decoded)) {$ _GET ['args'] = $ được giải mã; } // thêm kết quả đến $ _GET

Đó giải mã gốc yêu cầu (không bao gồm dấu gạch chéo hàng đầu - sẽ là hơi khác nhau nếu bạn sâu hơn xuống một hệ thống phân cấp, nhưng nguyên tắc là như nhau - và không bao gồm bất kỳ chuỗi truy vấn bổ sung) và giải mã tham số args theo các quy tắc bình thường của PHP và đặt nó vào $ _GET để bạn có thể xử lý nó cùng với phần còn lại của tham số chuỗi truy vấn $ _GET theo cách thông thường.

Tôi tin rằng điều này sẽ làm việc cho URL rỗng (http://example.com/) hoặc những người mà chỉ có một chuỗi truy vấn (http://example.com/?foo=1), cũng như các trường hợp đơn giản (http://example.com/bar) và trường hợp với một chuỗi truy vấn cũng như (http://example.com/bar?foo=1). Không có nghi ngờ phương pháp tiếp cận tương tự sẽ làm việc cho các ngôn ngữ khác.

Trong trường hợp cụ thể của bạn, bạn thực sự không muốn phần bổ sung được giải mã trong PHP. Đó là tốt, sử dụng rawurldecode thay vào đó, mà không làm cộng.

+0

Cảm ơn; đây là bài đăng duy nhất tôi thấy rằng trả lời đúng vấn đề của + dấu hiệu ở phần địa phương của URL. Cụm từ chính trong câu trả lời ở trên là "Trên thực tế không thể sử dụng quy tắc viết lại một mình. Apache giải mã URL trước khi đưa nó qua viết lại, nhưng nó không hiểu dấu cộng". – fooquency

Các vấn đề liên quan