2013-12-09 15 views
12

Tôi gặp sự cố với máy chủ của mình. Tôi có bốn liên kết gửi đến trang web khác nhau của trang web năng động của tôi mà trông giống như thế này:Liên kết ngoài Mã hóa URL dẫn đến '% 3F' và '% 3D' trên máy chủ Nginx

myurl.com/default/Site%3Fid%3D13 

Họ sẽ trông như thế này:

myurl.com/default/Site?id=13 

tôi biết rằng những %3F là một dãy thoát cho ?%3D là chuỗi thoát cho dấu bằng. Nhưng tôi nhận được lỗi 400 khi tôi sử dụng các liên kết đó. Tôi có thể làm gì với điều đó?

Bốn liên kết dành cho các trang web khác nhau và tôi hình dung theo thời gian sẽ có nhiều liên kết hơn như vậy. Vì vậy, một sửa chữa cho tất cả sẽ là hoàn hảo.

+0

@ John chỉ trong trường hợp bạn quên và không để ý, bounty bạn thiết lập sẽ hết hạn trong vòng vài giờ. –

Trả lời

8

Một cùng một câu hỏi chính xác đã thực sự hỏi trên mailing list nginx-ru khoảng một năm trước:

http://mailman.nginx.org/pipermail/nginx-ru/2013-February/050200.html

Câu trả lời hữu ích nhất, bởi một Nginx, Inc, nhân viên/nhà phát triển, Валентин Бартенев:

http://mailman.nginx.org/pipermail/nginx-ru/2013-February/050209.html

Если запрос приходит в таком виде, то это уже не парам тры, а имя запрошенного файла. Другое дело, что vị trí ищется по уже раскодированному адресу, о чем в документации написано.

dịch:

Nếu yêu cầu đi kèm trong một hình thức như vậy, sau đó những không còn là args, nhưng tên của tập tin được yêu cầu. Một điều nữa là, như được ghi chép, việc so khớp vị trí được thực hiện với một URI chuẩn hóa.

giải pháp đề nghị của ông, phiên dịch sang các ví dụ mẫu từ các câu hỏi ở đây tại SO, sau đó sẽ là:

location /default/Site? { 
    rewrite \?(.*)$ /default/Site?$1? last; 
} 

location = /default/Site { 
    [...] 
} 
+0

@ John và user3082653 - Có điều gì về câu trả lời của tôi không rõ ràng hoặc yêu cầu làm rõ thêm không? – cnst

0

Các URL là hoàn toàn hợp lệ. Các ký tự thoát mà nó chứa chỉ là, thoát. Đó là hoàn toàn tốt đẹp.

Mục đích là bạn có thể có tên yêu cầu (trong hầu hết các trường hợp tương ứng với tên tệp trên đĩa) là Site?id=13 và không Site và phần còn lại làm chuỗi truy vấn.

Tôi sẽ coi hành vi không tốt để có các ký tự trong tên tệp thực hiện điều này là cần thiết. Tuy nhiên, trong các đối số URL, nó có thể rất cần thiết.

Tuy nhiên, URL yêu cầu hợp lệ và có thể không phải là thứ bạn muốn. Do đó, đề nghị bạn nên sửa lỗi ở bất cứ nơi nào có ai đó đã nhặt nhầm URL ở địa điểm đầu tiên.

Tôi không thực sự hiểu tại sao bạn gặp lỗi 400; bạn nên nhận được một lỗi 404. Nhưng điều đó phụ thuộc vào thiết lập của bạn.Ngoài ra còn có các trường hợp, đặc biệt là với nginx, chủ yếu liên quan đến việc chuyển toàn bộ URL và phần URL cùng nhiều cấp độ (ví dụ proxy ngược, đối sánh cụm từ thông dụng từ URL và sử dụng chúng dưới dạng biến, v.v.) lỗi có thể xảy ra. Nhưng để xác minh điều này và khắc phục, chúng tôi cần biết thêm về thiết lập của bạn.

1

Các mẫu sau đây sẽ chuyển hướng tất cả các yêu cầu sai-looking (được xác định là có ? trong tên tập tin yêu cầu — mã hóa như %3F trong yêu cầu) vào những người ít sai trai, không phân biệt địa chỉ URL.

(Xin lưu ý rằng, như được thông báo đúng ở nơi khác, bạn không nên nhận các liên kết được tạo sai ở địa điểm đầu tiên, vì vậy, hãy sử dụng nó như một phương sách cuối cùng — chỉ khi bạn không thể sửa các liên kết sai hình thành khác, và bạn biết rằng yêu cầu đó đang cố gắng bởi các đại lý hợp lệ.)

server { 
    listen  [::]:80; 
    server_name localhost; 

    rewrite  ^/([^?]*)\?(.*)$ /$1?$2?  permanent; 
    location/{ 
     return 200 "id is $arg_id\n"; 
    } 
} 

Đây là ví dụ về cách nó sẽ làm việc — khi một yêu cầu tìm kiếm sai là gặp phải, nỗ lực sửa được thực hiện với một phản ứng 301 Moved Permanently với một được cho là đúng Location tiêu đề phản hồi, điều này sẽ làm cho trình duyệt tự động cấp lại yêu cầu cho loc mới được cung cấp ation:

opti# curl -6v "http://localhost/default/Site%3Fid%3D13" 
* About to connect() to localhost port 80 (#0) 
* Trying ::1... 
* connected 
* Connected to localhost (::1) port 80 (#0) 
> GET /default/Site%3Fid%3D13 HTTP/1.1 
> User-Agent: curl/7.26.0 
> Host: localhost 
> Accept: */* 
> 
< HTTP/1.1 301 Moved Permanently 
< Server: nginx/1.4.1 
< Date: Wed, 15 Jan 2014 17:09:25 GMT 
< Content-Type: text/html 
< Content-Length: 184 
< Location: http://localhost/default/Site?id=13 
< Connection: keep-alive 
< 
<html> 
<head><title>301 Moved Permanently</title></head> 
<body bgcolor="white"> 
<center><h1>301 Moved Permanently</h1></center> 
<hr><center>nginx/1.4.1</center> 
</body> 
</html> 
* Connection #0 to host localhost left intact 
* Closing connection #0 

Lưu ý rằng không có những nỗ lực sửa chữa được thực hiện trên các yêu cầu hợp lý-looking:

opti# curl -6v "http://localhost/default/Site?id=13" 
* About to connect() to localhost port 80 (#0) 
* Trying ::1... 
* connected 
* Connected to localhost (::1) port 80 (#0) 
> GET /default/Site?id=13 HTTP/1.1 
> User-Agent: curl/7.26.0 
> Host: localhost 
> Accept: */* 
> 
< HTTP/1.1 200 OK 
< Server: nginx/1.4.1 
< Date: Wed, 15 Jan 2014 17:09:30 GMT 
< Content-Type: application/octet-stream 
< Content-Length: 9 
< Connection: keep-alive 
< 
id is 13 
* Connection #0 to host localhost left intact 
* Closing connection #0 
Các vấn đề liên quan