在IIS7中使用ARR(Application Request Routing)反向代理虛擬目錄到Nodejs站點


目標:

 1.訪問www.arrdemo.com/proxy 跳轉到 localhost:8898的Nodejs站點

 2.Nodejs站點的頁面可以返回到瀏覽器,包括js,css,圖片

 3.Nodejs站點的 res.redirect(' ') 重定向要正確,包括站內跳轉和站外跳轉

步驟:

1. 新建站點綁定域名www.arrdemo.com,配置host文件指向本機,新建虛擬目錄proxy。  

注意去掉虛擬目錄->壓縮->"啟用動態內容壓縮"和“啟用靜態內容壓縮” 前面的勾選。否則會出現如下錯誤:

HTTP 錯誤 500.52 - URL Rewrite Module Error.

HTTP 響應的內容已編碼(“gzip”)時,無法應用出站重寫規則。

  2.啟動Nodejs站點 http://localhost:8898

  這個站點是《nodejs開發指南》上的microblog實例,學習過程中改成了Express4.13.1版本。

  3.安裝ARR,啟用Proxy

   下載地址(http://www.iis.net/downloads/microsoft/application-request-routing)

  安裝完成后,打開IIS->選中服務器名稱->雙擊 右側功能視圖 IIS 節點下的Application Request Routing Cache->點擊 右側操作視圖Proxy節點下的Server Proxy Settings->勾選上Enable Proxy前面的復選框

     

 

 

 

 

 4.配置虛擬目錄的URL重寫規則

  在IIS節點,站點節點,虛擬目錄節點都可以配置URL重新規則,並且一級級繼承。配置完成后信息保存到對應的web.config文件中。所以如果www.arrdemo.com部署在多個服務器上,每個服務器的proxy虛擬目錄都需要重定向時可以采取拷貝proxy下的web.config文件的方式快速部署。這里只在proxy虛擬目錄下部署,排除繼承的影響。

 首先,配置入站規則。把http://www.arrdemo.com/proxy/reg 這樣的url重寫成 http://localhost:8898/reg

 

雙擊"URL重寫",從入站規則下選擇空白規則模板。剩下的注意細看圖片注釋:

到這一步正常情況下在瀏覽器里輸入http://www.arrdemo.com/proxy,應該可以看到有內容輸出了,但是沒有任何樣式和js效果。如下圖:

這是因為入站規則能把請求轉發到nodejs里,nodejs返回的html內容再轉發到瀏覽器。但html里的css和js還有圖片的路徑一般都是相對站點根路徑的,不會加上虛擬目錄proxy,所以前端看不到任何樣式。

這時候該出站規則上場了。。。。。。。

 然后,配置出站規則。把http://localhost:8898/bootstrap/..... 這樣的url轉換成http://www.arrdemo.com/proxy/bootstrap/.....

我這里就拿已經配置好的規則演示了。規則多了分先后順序,如果匹配上了是否”停止處理“很重要。比如:匹配上兩個重新類型的規則,那么就會在輸出里出現proxy/proxy的情形,導致出錯。

第一個規則 bbbb,處理輸出的js、css、圖片等路徑不對問題。

 

做完第一個規則,本應萬事大吉,只剩喝酒了。然而。。。。然而。。。。。打開網頁登陸后跳轉到首頁的地址變成了 www.arrdemo.com 沒有加上proxy。接着下一規則走起。。。

第二個規則處理res.redirect('/'); 這種站內跳轉 

站內跳轉需要在輸出時添加proxy,主要是檢查  {RESPONSE_STATUS} 變量為302, 然后在 重寫時輸出 /proxy{R:1},規則如下(請細看圖):

這樣處理后站內跳轉的就沒問題了。

 

第三個規則處理res.redirect('http://www.baidu.com'); 這種站外跳轉

  跟第二個規則的區別就是這種跳轉不做任何操作,直接拋出,規則如下:

現在再去瀏覽器里訪問一下試試吧,如果還不行,請重啟站點。

總結:

1.完整的配置文件奉上

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <outboundRules>
                <clear />
                <rule name="bbbbb" enabled="true" stopProcessing="false">
                    <match filterByTags="A, Area, Base, Form, Frame, Head, Img, Input, Link, Script" pattern="^(.*)" />
                    <conditions logicalGrouping="MatchAny" trackAllCaptures="true">
                        <add input="{URL}" pattern="^/proxy.*" />
                    </conditions>
                    <action type="Rewrite" value="/proxy{R:1}" />
                </rule>
                <rule name="站外重定向" enabled="true" stopProcessing="true">
                    <match serverVariable="RESPONSE_LOCATION" pattern="^http://[^/]+/(.*)" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="true">
                        <add input="{RESPONSE_STATUS}" pattern="^302" />
                    </conditions>
                    <action type="None" />
                </rule>
                <rule name="站外跳轉2" enabled="true" stopProcessing="true">
                    <match serverVariable="RESPONSE_LOCATION" pattern="^https://[^/]+/(.*)" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="true">
                        <add input="{RESPONSE_STATUS}" pattern="^302" />
                    </conditions>
                    <action type="None" />
                </rule>
                <rule name="站內從定向" enabled="true">
                    <match serverVariable="RESPONSE_LOCATION" pattern="^(.*)" />
                    <conditions logicalGrouping="MatchAny" trackAllCaptures="true">
                        <add input="{RESPONSE_STATUS}" pattern="^302" />
                    </conditions>
                    <action type="Rewrite" value="/proxy{R:1}" />
                </rule>
            </outboundRules>
            <rules>
                <remove name="aaaaa" />
                <rule name="aaaaa" stopProcessing="true">
                    <match url="^(.*)" />
                    <conditions />
                    <serverVariables />
                    <action type="Rewrite" url="http://localhost:8898/{R:1}" logRewrittenUrl="true" />
                </rule>
            </rules>
        </rewrite>
        <urlCompression doStaticCompression="false" doDynamicCompression="false" />
    </system.webServer>
</configuration>
proxy 下的 web.config

2.查找資料除了百度、必應最應該想到的就是官網幫助文檔

每一步操作右側都有個幫助的鏈接,點進去是詳細的英文文檔。

不過也不要完全相信,比如配置重定向跳轉時,文檔里是這樣的:

<outboundRules>
    <!-- This rule changes the domain in the HTTP location header for redirection responses -->
    <rule name="Change Location Header">
        <match serverVariable="RESPONSE_LOCATION" pattern="^http://[^/]+/(.*)" />
        <conditions>
            <add input="{RESPONSE_STATUS}" pattern="^301" />
        </conditions>
        <action type="Rewrite" value="http://{HTTP_HOST}/{R:1}"/>
    </rule>
</outboundRules>

我明明感覺應該是302啊,這里為什么是301;還有Rewrite 里那么寫真的對嗎?我不確定,不過也得到一個思路使用RESPONSE_STATUS變量。

微服務、nodejs好像很火的樣子,我也在嘗試。希望這篇文章可以讓node+nginx實現域名解析的人們多一種解決思路 node+iis+arr實現域名解析。

 


2018年4月11日更新:

有朋友用Nextcloud+ONLYOFFICE Document Server做了個文檔管理雲盤系統,通過IIS的反向代理訪問,出現了資源鏈接未替換的錯誤。他最后找到一種只配置入站規則就可以實現全域名替換的方案,經測試可用。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="INIT_SERVER_VARIABLE_FROM_PROXY" stopProcessing="false">
          <match url=".*" /> 
          <serverVariables>          
            <set name="HTTP_THE_SCHEME" value="{HTTP_X_FORWARDED_PROTO}" replace="true" />            
            <set name="HTTP_THE_HOST" value="{HTTP_X_FORWARDED_HOST}" replace="true" />
          </serverVariables>
          <action type="None" />
        </rule>    
        <rule name="INIT_SERVER_VARIABLE_DEFAULT" stopProcessing="false">
          <match url=".*" /> 
          <conditions trackAllCaptures="true">
            <add input="{HTTPS}s" pattern="on(s)|offs" />
          </conditions>
          <serverVariables>          
             <set name="HTTP_THE_SCHEME" value="http{C:1}" replace="false" />            
             <set name="HTTP_THE_HOST" value="{HTTP_HOST}" replace="false" />                        
          </serverVariables>
          <action type="None" />
        </rule>    
        <rule name="DocumentServerRewrite" enabled="true">
          <match url="^documentserver-virtual-path(.*)" />
            <conditions trackAllCaptures="true">
              <add input="{HTTPS}s" pattern="on(s)|offs" />
            </conditions>
            <serverVariables>              
              <set name="HTTP_X_FORWARDED_PROTO" value="{HTTP_THE_SCHEME}" replace="true" />
              <set name="HTTP_X_FORWARDED_HOST" value="{HTTP_THE_HOST}/documentserver-virtual-path" replace="true" />
            </serverVariables>
            <action type="Rewrite" url="http://docservice{R:1}" />
         </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>
web.config

 

  

開博第一篇,推薦、推薦、推薦 一下吧,重要的事情說三遍。

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM