Điểm:1

Sự khác biệt giữa $uri và $uri/ trong chỉ thị try_files là gì?

lá cờ in

Đây là cấu hình:

chỉ số index.html;
địa điểm / {
    try_files $uri $uri/ = 404;
}

Tôi đưa ra yêu cầu tại http://localhost/path/a/. Tôi cho rằng đây là URI, vì vậy ở giai đoạn $uri, try_files sẽ xem /path/a/ và cung cấp index.html nếu có.

Tôi đọc từ các tài liệu rằng Có thể kiểm tra sự tồn tại của thư mục bằng cách chỉ định dấu gạch chéo ở cuối tên, ví dụ: â$uri/â. nhưng điều này không có ý nghĩa gì đối với tôi.

Điểm:0
lá cờ gr

Nó chính xác là $uri/ phần khiến nginx giả sử một URI có thể là tên thư mục và tìm kiếm sự hiện diện của tệp chỉ mục bên trong nó.

Giả sử cấu trúc thư mục sau:

/var/www/html
         âââ a
         â âââ index.html
         âââ b
         â âââ index.html
         â âââ index.htm
         âââ c
         â âââ test.html
         ...

và cấu hình nginx sau:

người phục vụ {
    gốc/var/www/html;
    chỉ mục index.htm index.html;
    địa điểm / {
        try_files $uri $uri/ =404;
    }
}

Đây là những gì đã xảy ra với những điều sau đây Xoăn yêu cầu:

  • cuộn tròn http://localhost/a
    

    Trả về một chuyển hướng:

    HTTP/1.1 301 được di chuyển vĩnh viễn
    Vị trí: http://localhost/a/
    
  • cuộn tròn http://localhost/a/
    

    Trả về /var/www/html/a/index.html nội dung tập tin.

  • cuộn tròn http://localhost/b
    

    Trả về một chuyển hướng:

    HTTP/1.1 301 được di chuyển vĩnh viễn
    Vị trí: http://localhost/b/
    
  • cuộn tròn http://localhost/b/
    

    Trả về /var/www/html/b/index.htm nội dung tệp (sự tồn tại của tệp chỉ mục được kiểm tra theo thứ tự chúng được chỉ định bằng cách sử dụng mục lục chỉ thị).

  • cuộn tròn http://localhost/c
    

    Trả về một chuyển hướng:

    HTTP/1.1 301 được di chuyển vĩnh viễn
    Vị trí: http://localhost/c/
    
  • cuộn tròn http://localhost/c/
    

    Vì không có tệp chỉ mục trong /var/www/html/c/ danh mục, Xoăn lệnh sẽ trả về một HTTP 403 bị cấm trừ khi bạn có một tự động lập chỉ mục; chỉ thị trong cấu hình của bạn (trong trường hợp đó nginx sẽ trả về /var/www/html/c/ danh sách thư mục).

Nếu cấu hình nginx của bạn sẽ giống như

người phục vụ {
    gốc/var/www/html;
    chỉ mục index.htm index.html;
    địa điểm / {
        try_files $uri =404;
    }
}

mỗi yêu cầu trên bây giờ sẽ trả về một Không tìm thấy HTTP 404 lỗi. Một tự động lập chỉ mục chỉ thị, nếu có mặt, sẽ không có hiệu lực. Cách duy nhất để có được một index.html nội dung sẽ chỉ định nó một cách rõ ràng, ví dụ: http://localhost/a/index.html, http://localhost/b/index.htm vân vân.

Điều rất quan trọng nhưng hoàn toàn không rõ ràng là một mục lục chỉ thị đang được sử dụng với try_files $uri $uri/ =404 có thể gây ra một chuyển hướng nội bộ. Ví dụ: nếu bạn sẽ có cấu hình sau:

người phục vụ {
    gốc/var/www/html;
    chỉ mục index.htm index.html;
    địa điểm / {
        add_header X-Test test1;
        try_files $uri $uri/ =404;
    }
    vị trí /a/index.html {
        add_header X-Test test2;
    }
}

yêu cầu http://localhost/a/ sẽ gây ra chuyển hướng nội bộ từ /một/ đến /a/index.html và trả lại /var/www/html/a/index.html nội dung tệp với tùy chỉnh Kiểm tra X tiêu đề được đặt thành kiểm tra2, không để kiểm tra1!

Điều cuối cùng đáng nói là try_files $uri $uri/ =404; là hành vi nginx mặc định, vì vậy

địa điểm / {
    try_files $uri $uri/ =404;
}

địa điểm / {}

vị trí hoàn toàn bằng nhau.

Cập nhật

Một câu hỏi bổ sung từ OP:

Suy nghĩ của tôi là: $uri kiểm tra URI như nó vốn có và $uri/ kiểm tra URI dưới dạng thư mục tìm kiếm tệp chỉ mục. Vì http://localhost/a với try_files $uri /file.html =404; tôi có tệp.html. Tốt cho bây giờ! Vì http://localhost/a với try_files $uri/ /file.html =404; tôi có tệp.html quá. Tại sao? tôi đã mong đợi index.html. Hơn nữa, try_files $uri $uri/ /file.html =404; sẽ giúp tôi index.html.

Một câu hỏi thực sự tốt! Nếu không trả lời nó, toàn bộ câu trả lời sẽ không đầy đủ. Hãy xem những gì xảy ra ở đây.

http://localhost/a/ yêu cầu và try_files $uri/ /file.html =404; trong cấu hình nginx của bạn, ở bước đầu tiên nginx đã kiểm tra /var/www/html/a/ thư mục để trở thành một thư mục, tiếp theo hãy kiểm tra nó để tìm sự hiện diện của tệp chỉ mục, đã tìm thấy một index.html tệp bên trong nó và thực hiện chuyển hướng nội bộ từ /một/ đến /a/index.html. Ở bước thứ hai, ở trong cùng một khối vị trí, nginx kiểm tra /var/www/html/a/index.html vì là một thư mục, nhưng không phải vậy! Và kể từ khi bạn không có một $uri thành phần như một try_files tham số chỉ thị, nó sẽ đi kiểm tra tiếp theo cho /var/www/html/file.html tệp, tìm thấy nó và trả về nội dung của nó.

Bạn có thể nghĩ rằng việc sử dụng try_files chỉ thị mà không có một $uri tham số là hoàn toàn vô dụng do đó. Thông thường là như vậy, nhưng nó có thể là một trường hợp sử dụng để làm điều đó, chẳng hạn như khi bạn muốn ẩn cấu trúc trang web nội bộ của mình. Đây là một ví dụ:

người phục vụ {
    gốc/var/www/html;
    chỉ số index.html;
    địa điểm / {
        try_files $uri/ =404;
    }
    vị trí ~ /index\.html$ {
        nội bộ; # chỉ có thể truy cập thông qua viết lại URI nội bộ
        try_files $uri =404;
    }
    vị trí ~ \.(js|css|jpe?g|png)$ {
        # phục vụ nội dung theo cách thông thường
        try_files $uri =404;
    }
}

Làm điều đó vị trí ~ /index\.html$ { ... } một nội bộ, bạn ngăn chặn truy cập trực tiếp vào của bạn index.html tập tin thông qua các yêu cầu như http://localhost/a/index.html (một Không tìm thấy HTTP 404 sẽ được trả lại thay thế). Tuy nhiên yêu cầu như http://localhost/a/ vẫn khả thi do URI nội bộ được viết lại bởi mục lục chỉ đạo cùng với try_files $uri/ =404 một.

lafleur avatar
lá cờ in
Lời giải thích tuyệt vời! Suy nghĩ của tôi là: $uri kiểm tra URI nguyên trạng và $uri/ kiểm tra URI dưới dạng thư mục tìm kiếm tệp chỉ mục. Đối với http://localhost/a `try_files $uri /file.html = 404; ` Tôi nhận được file.html. Tốt cho bây giờ! Đối với http://localhost/a `try_files $uri/ /file.html = 404; ` Tôi cũng nhận được file.html. Tại sao? Tôi đã mong đợi index.html. Hơn nữa, `try_files $uri $uri/ /file.html = 404;` sẽ lấy cho tôi index.html.
Ivan Shatsky avatar
lá cờ gr
Câu hỏi hay! Xem cập nhật cho câu trả lời.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.