Sự khác biệt giữa các biến Nginx $ host, $ http_host và $ server_name là gì?


42

Phần chênh lệch giữa ba biến Nginx là gì $host, $http_host$server_name?

Tôi có một quy tắc viết lại trong đó tôi không chắc chắn nên sử dụng quy tắc nào:

location = /vb/showthread.php {
    # /vb/showthread.php?50271-What-s-happening&p=846039
    if ($arg_p) {
        return 301 $scheme://$host/forum/index.php?posts/$arg_p/;
        }

Tôi đang tìm kiếm một câu trả lời không chỉ nói 'sử dụng biến ___ trong quy tắc viết lại của bạn' mà còn giải thích sự khác biệt về lý thuyết giữa chúng.


Tôi nhận ra sau đó tôi thậm chí không cần chỉ định $scheme$host... return 301 /forum/index.php?posts/$arg_p/;hoạt động tốt.
Jeff Widman

Hầu hết các trình duyệt sẽ hoạt động với URL tương đối trong chuyển hướng, nhưng tiêu chuẩn ( w3.org/Prot Protocol / rfc2616 / rfc2616-sec14.html ) yêu cầu url tuyệt đối trong Locationtiêu đề.
Cthulhu

Câu trả lời:


54

Bạn hầu như luôn luôn nên sử dụng $host, vì đó là người duy nhất được đảm bảo có thứ gì đó hợp lý bất kể tác nhân của người dùng hoạt động như thế nào, trừ khi bạn đặc biệt cần ngữ nghĩa của một trong các biến khác.

Sự khác biệt được giải thích trong tài liệu nginx :

  • $host chứa "theo thứ tự ưu tiên này: tên máy chủ từ dòng yêu cầu hoặc tên máy chủ từ trường tiêu đề yêu cầu 'Máy chủ' hoặc tên máy chủ khớp với yêu cầu"
  • $http_host chứa nội dung của trường tiêu đề "Máy chủ" HTTP, nếu nó có trong yêu cầu
  • $server_namechứa server_namemáy chủ ảo đã xử lý yêu cầu, như được xác định trong cấu hình nginx. Nếu a serverchứa nhiều server_names, chỉ cái đầu tiên sẽ có mặt trong biến này.

Vì việc các tác nhân người dùng gửi tên máy chủ trong dòng yêu cầu thay vì trong tiêu đề Host: là điều hợp pháp, mặc dù điều này hiếm khi được thực hiện trừ khi kết nối với proxy, bạn phải tính đến điều này.

Bạn cũng phải tính đến trường hợp tác nhân người dùng hoàn toàn không gửi tên máy chủ, ví dụ như các yêu cầu HTTP / 1.0 cổ đại và phần mềm được viết xấu hiện đại. Bạn có thể làm như vậy bằng cách chuyển hướng chúng sang một máy chủ ảo bắt tất cả không phục vụ bất cứ thứ gì, nếu bạn đang phục vụ nhiều trang web hoặc nếu bạn chỉ có một trang web trên máy chủ của mình, bạn có thể xử lý mọi thứ thông qua một máy chủ ảo duy nhất . Trong trường hợp sau, bạn cũng phải tính đến điều này.

Chỉ các $hosttài khoản biến cho tất cả những điều có thể mà tác nhân người dùng có thể làm khi tạo yêu cầu HTTP.


2
Mặt khác, $server_namean toàn khi Host:trường từ UA có thể chứa nội dung tùy ý.
Cthulhu

1
$ Http_host có được đổi tên thành $ hostname không? Tôi không thể tìm thấy biến như vậy trong tài liệu Nginx. $ hostname là tên tương tự nhất tôi đoán.
darkbaby123

3
@ darkbaby123 Không, nó không được đổi tên thành bất cứ thứ gì. Xem tài liệu .
Michael Hampton

1
Bây giờ tôi hiểu biến http_ <name> có nghĩa là gì. Cảm ơn bạn!
darkbaby123

0

Tôi muốn thêm một điểm quan trọng khác không được đề cập trong câu trả lời được chấp nhận.

$hostlàm KHÔNG có số cổng, trong khi $http_hostDO bao gồm số cổng.

chỉnh sửa : không phải lúc nào.

Tôi thiết lập tiêu đề "add_header Y-blog-http_host" $ http_host "luôn;"

Sau đó curl -I -L domain.com:80(hoặc 443) và tiêu đề hoàn toàn không hiển thị số cổng. Được xác minh bằng nginx-thêm 1.10.3. Là bởi vì đó là cổng http (s) phổ biến hoặc cấu hình nginx? Nhận xét này chỉ để nói những điều không phải lúc nào cũng hành xử theo cách bạn nghĩ.


0

Tôi cũng vật lộn với điều này trong một thời gian. Mọi thứ trở nên rõ ràng khi tôi hiểu rằng $ http_XXXXX đề cập đến tất cả các biến tiêu đề được khai báo.

Vì vậy, $ http_user_agent, $ http_Vferer là "ĐẠI LÝ NGƯỜI DÙNG", "TÀI LIỆU THAM KHẢO" được tham chiếu trong chữ thường và dấu gạch dưới. Điều này giải thích cho tôi địa ngục $ http_upTHER đến từ đâu trong nhiều mẫu cấu hình NGINX.

Đọc nó từ https://stackoverflow.com/questions/15414810/whats-the-difference-of-host-and-http-host-in-nginx

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.