2015-07-07 19 views
5

Tôi có nginx location chỉ thị nhằm mục đích là "loại bỏ" tiền tố bản địa hóa từ URI cho chỉ thị proxy_pass.Nginx - mã hóa (chuẩn hóa) một phần của URI

Ví dụ, để làm cho URI http://example.com/en/lalala sử dụng proxy_pass http://example.com/lalala

location ~ '^/(?<locale>[\w]{2})(/(?<rest>.*))?$' { 
     ... 
     proxy_pass http://example/$rest; 
     ... 
} 

Bằng cách này, biến rest sẽ được giải mã khi truyền cho proxy_pass directeve. Nó có vẻ là một dự kiến ​​behavior.

Vấn đề là khi URI của tôi chứa mã hóa không gian %20 truyền từ client

http://example.com/lala%20lala 

nginx giải mã URI để

http://example.com/lala lala 

tôi có thể nhìn thấy nó trong error.log tôi.

Câu hỏi đặt ra là - liệu có thể sử dụng mã hóa rest biến bằng cách nào đó khi nó được truyền từ máy khách? Nếu tôi làm điều gì đó hoàn toàn sai, xin vui lòng, đề xuất đúng cách.

Cảm ơn bạn.

Trả lời

6

Vâng, hành vi này được dự kiến ​​mặc dù tài liệu cũng nói:

Nếu proxy_pass được quy định mà không có một URI, yêu cầu URI được truyền đến máy chủ theo hình thức giống như được gửi bởi một khách hàng khi yêu cầu ban đầu được xử lý hoặc theo yêu cầu bình thường đầy đủ URI được thông qua khi xử lý URI thay đổi:

location /some/path/ { 
    proxy_pass http://127.0.0.1; 
} 

kỹ sư Nginx nói như vậy: https://serverfault.com/questions/459369/disabling-url-decoding-in-nginx-proxy

Tuy nhiên nếu bạn thêm $ REQUEST_URI để proxy_pass (và dải locale trước nó có thể làm việc như said bởi kỹ sư Nginx):

set $modified_uri $request_uri; 

if ($modified_uri ~ "^/([\w]{2})(/.*)") { 
set $modified_uri $1; 
} 

proxy_pass http://example$modified_uri; 
+0

cảm ơn rất nhiều. Tôi biết về $ request_uri nhưng kiến ​​thức hiện tại của tôi về nginx không cho phép tôi sửa đổi URI đúng cách. –

+0

Hãy nhớ rằng nếu bạn sử dụng $ request_uri thì IT SILL KHÔNG THAY ĐỔI nếu một chuyển hướng nội bộ được thực hiện, chẳng hạn như khi viết lại được thực hiện hoặc áp dụng chỉ thị error_page. Chỉ có $ uri thay đổi trong những trường hợp đó, nhưng $ uri đã được giải mã nên nó không thể được sử dụng như là một thay thế chung cho $ request_uri. –

4

Tôi đã có một số thành công bằng cách sử dụng sau đây với Confluence và các ứng dụng khác Atlassian đằng sau nginx nơi ký tự đặc biệt như() < vấn đề> [] đã gây ra.

location /path { 
    # [... other proxy options ...] 

    # set proxy path with regex 
    if ($request_uri ~* "/path(/.*)") { 
    proxy_pass http://server:port/path$1; 
    break; 
    } 

    # fallback (probably not needed) 
    proxy_pass http://server:port/path; 
} 
+0

Cảm ơn bạn rất nhiều. Điều này đã kết thúc 2 ngày của turture :) –