IIS URL Rewrite hỗ trợ biến máy chủ thành mỗi phần URL và tiêu đề http. Tuy nhiên, có một biến thường được sử dụng tại máy chủ không có sẵn. Đó là giao thức HTTP hoặc HTTPS.
Bạn có thể dễ dàng kiểm tra xem trang web yêu cầu sử dụng HTTP hoặc HTTPS, nhưng chỉ làm việc trong điều kiện là một phần của rule. Không phải là biến có sẵn để tự động thiết lập các giao thức trong phần hành động của rule. Những gì tôi muốn là sẽ có một biến như {HTTP_PROTOCOL} trong đó sẽ có một giá trị của 'HTTP' hoặc 'HTTPS'. Có một biến máy chủ được gọi là {HTTPS}, nhưng giá trị 'on' và 'off' là không thực tế trong hành động. Bạn cũng có thể sử dụng {SERVER_PORT} hoặc {SERVER_PORT_SECURE}, nhưng một lần nữa, chúng không phải là hữu ích trong hành động này.
Các quy tắc sau đây sẽ chuyển hướng lưu lượng truy cập cho http(s)://localtest.me/ đến http://www.localtest.me/.
<rule name="Redirect to www">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^localtest\.me$" />
</conditions>
<action type="Redirect" url="http://www.localtest.me/{R:1}" />
</rule>
Vấn đề là nó buộc các yêu cầu HTTP ngay cả khi yêu cầu ban đầu là cho HTTPS.
Tôi nghĩ đến bốn cách khác nhau để xử lý, và tùy thuộc vào tình hình thực tế của bạn, bạn có thể nghiêng về phía bất kỳ. Đừng để những sự lựa chọn áp đảo bạn. Hãy giữ nó đơn giản, phương án 1 là những gì tôi sử dụng hầu hết, Phương án 2 là được đề xuất và là lựa chọn an toàn nhất, và Lựa chọn 3 và Lựa chọn 4 được xem xét nếu bạn có một tình huống độc hơn. Tất cả bốn lựa chọn sẽ làm việc cho hầu hết các tình huống.
Lựa chọn 1 - CACHE_URL, nguyên tắc đơn
Có một biến máy chủ có các giao thức trong nó; {CACHE_URL}. Biến máy chủ này chứa toàn bộ chuỗi URL (ví dụ http://www.localtest.me:80/info.aspx?id=5) Tất cả chúng cần phải làm là giải nén HTTP hoặc HTTPS và chúng sẽ được thiết lập.
... Bạn có thể sử dụng một điều kiện về biến CACHE_URL và một tham chiếu trở lại trong URL rewrite. Vấn đề đó là sau đó cần phải phù hợp với tất cả các điều kiện có thể là vấn đề nếu quy tắc của bạn phụ thuộc vào logic "or" phù hợp cho điều kiện.
Nếu bạn có nhiều điều kiện thiết lập đến "Match Any" hơn là "Match All", thì tùy chọn này sẽ không hoạt động. Tuy nhiên, tôi thấy rằng 95% tất cả các quy tắc mà tôi viết sử dụng "Match All". Thông báo trước là nếu bạn sử dụng "Match", thì bạn phải xem xét một trong hai tùy chọn tiếp theo.
Đây là cách nó hoạt động. Thêm điều kiện để kiểm tra cho {CACHE_URL} với pattern "^(.+)://":
Làm thế nào bạn có back-reference đến rước ://, đó là HTTP hoặc HTTPS. Trong URL Rewrite 2.0 hoặc mới hơn, bạn có thể check "Track capture groups across conditions", làm cho tình trạng đó điều kiện đầu tiên, và bạn có tham chiếu đến {C:1}.
Ví dụ "Redirect to www" với sự hỗ trợ cho việc duy trì các giao thức:
<rule name="Redirect to www" stopProcessing="true">
<match url="(.*)" />
<conditions trackAllCaptures="true">
<add input="{CACHE_URL}" pattern="^(.+)://" />
<add input="{HTTP_HOST}" pattern="^localtest\.me$" />
</conditions>
<action type="Redirect" url="{C:1}://www.localtest.me/{R:1}" />
</rule>
Lựa chọn 2 - Sử dụng Rewrite Map
Đối với quy tắc an toàn hơn mà làm việc cho cả hai tình huống "Match" và "Match All", bạn có thể sử dụng giải pháp Rewrite Map. Nói cách khác, nếu bạn chọn sử dụng phương thức duy nhất để xử lý các giao thức, bạn sẽ được an toàn.
Sau khi bạn tạo ra một Rewrite Map được gọi là MapProtocol, bạn có thể sử dụng "{MapProtocol:{HTTPS}}" cho các giao thức trong bất kỳ quy tắc hành động. Sau đây là ví dụ sử dụng Rewrite Map.
<rewrite>
<rules>
<rule name="Redirect to www" stopProcessing="true">
<match url="(.*)" />
<conditions trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="^localtest\.me$" />
</conditions>
<action type="Redirect"
url="{MapProtocol:{HTTPS}}://www.localtest.me/{R:1}" />
</rule>
</rules>
<rewriteMaps>
<rewriteMap name="MapProtocol">
<add key="on" value="https" />
<add key="off" value="http" />
</rewriteMap>
</rewriteMaps>
</rewrite>
Lựa chọn 3 - CACHE_URL, Multi-rule
Nếu bạn có nhiều quy tắc mà sử dụng các giao thức, bạn có thể tạo ra biến máy chủ của riêng bạn có thể được sử dụng trong quy tắc tiếp theo. Tùy chọn này là không dễ dàng để thiết lập hơn Lựa chọn 2 ở trên, nhưng bạn có thể sử dụng nó nếu bạn thích dễ dàng hơn để nhớ cú pháp {HTTP_PROTOCOL} vs {MapProtocol: {HTTPS}}.
Vấn đề với quy tắc này là nếu bạn không có quyền truy cập vào cấp độ máy chủ (ví dụ như trong một môi trường chia sẻ) thì bạn không thể thiết lập các biến máy chủ mà không được phép.
Đầu tiên, tạo quy tắc và đặt nó ở trên cùng của bộ quy tắc. Bạn có thể tạo ra điều này ở cấp độ máy chủ, trang web hoặc thư mục con. Tuy nhiên, nếu bạn tạo ra nó ở cấp độ trang web hoặc thư mục con sau đó biến máy chủ HTTP_PROTOCOL cần được chấp thuận ở cấp độ máy chủ. Điều này có thể đạt được trong IIS Manager bằng cách vào URL Rewrite ở cấp độ máy chủ, nhấp vào "View Server Variables" từ khung Actions, và thêm HTTP_PROTOCOL. Nếu bạn tạo ra các quy tắc ở cấp độ máy chủ thì bước này là không cần thiết.
Sau đây là ví dụ về nguyên tắc đầu tiên để tạo ra các HTTP_PROTOCOL và sau đó rule sử dụng nó.
<rule name="Create HTTP_PROTOCOL">
<match url=".*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{CACHE_URL}" pattern="^(.+)://" />
</conditions>
<serverVariables>
<set name="HTTP_PROTOCOL" value="{C:1}" />
</serverVariables>
<action type="None" />
</rule>
<rule name="Redirect to www" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="^localtest\.me$" />
</conditions>
<action type="Redirect" url="{HTTP_PROTOCOL}://www.localtest.me/{R:1}" />
</rule>
Phương án 4 - Multi-rule
Ví dụ làm thế nào để đạt được điều tương tự với nhiều quy tắc. Tôi không thấy bất kỳ lý do gì để sử dụng nó trong ví dụ trước, nhưng tôi sẽ đưa ví dụ nào. Lưu ý rằng nó sẽ chỉ làm việc với thiết lập "Match All" cho các điều kiện.
<rule name="Redirect to www - http" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="^localtest\.me$" />
<add input="{HTTPS}" pattern="off" />
</conditions>
<action type="Redirect" url="http://www.localtest.me/{R:1}" />
</rule>
<rule name="Redirect to www - https" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="^localtest\.me$" />
<add input="{HTTPS}" pattern="on" />
</conditions>
<action type="Redirect" url="https://www.localtest.me/{R:1}" />
</rule>
Kết luận
Trên đây là bốn ví dụ làm việc của phương pháp gọi giao thức (HTTP hoặc HTTPS) từ các action của rule URL Rewrite. Bạn có thể sử dụng phương pháp nào bạn thích nhất. Tôi đã liệt kê chúng theo thứ tự, mặc dù tôi có thể nhìn thấy một số người thích Lựa chọn 2 là lựa chọn đầu tiên của họ.