Web API接口站點,引入了swagger來實時生成在線的api文檔,也便於api接口的在線測試。swagger:The World's Most Popular Framework for APIs.
本地測試沒有問題。 發布到生產,問題出現了。——線上部署的站點是用nginx做的3個節點的負載。nginx配置了公開的域名,並且與3個節點iis上的站點做了映射。3個單節點的端口不是默認的80,由此問題產生了:當訪問swagger時,swagger自動獲取的文檔的url包含了這個端口,因為站點對外公開的僅僅是域名,用端口訪問不了,所以,取不到swagger文檔了。

當然,手動把這個explorer里的端口去掉是可以顯示出來接口列表的。
類似的問題還出現在當模擬調用一個接口時,由於同時顯示了端口,所以無法將請求發送到服務端,導致錯誤響應。見下圖:
由於swagger的代碼是集成到了一個dll里了,項目文件中並沒有swagger的任何靜態腳本、圖片、樣式文件,我們沒辦法修改其源碼。
我曾試圖將這個疑問提到csdn論壇里http://bbs.csdn.net/topics/391964196,得到的多是不明我意的批判。
昨天,突然想到,是否可以通過截獲http響應,然后修改其響應內容呢(即去掉響應內容里的那個端口)。
通過在程序站點的Global.ascx.cx里嘗試通過EndRequest事件,行不通。
接下來,叫來開發組里2個同學,說明情況后,一個同學說可以通過攔截http請求來搞定。
第二天,他果真實現了。 通過chrome瀏覽器的調試工具推斷出來影響這2個地方的,來自於swagger的2個js文件。然后,我們從chrome里獲取到這2個js代碼,修改其中獲取網站url的代碼(如果是生產環境域名,則replace掉端口),然后把js文件保存在網站文件的Scripts文件夾里,最后在Global.ascx.cx里做請求攔截處理。

protected void Application_BeginRequest(object sender, EventArgs e) { if (Request.Url.ToString().Contains("marked-js")) { Response.Redirect("/Scripts/swagger-oauth.js"); } else if (Request.Url.ToString().Contains("swagger-ui-min-js")) { Response.Redirect("/Scripts/swagger-ui-min.js"); } }
我這邊還有一個解決辦法,既然通過瀏覽器調試工具的network里可以看到調用的js,那么,我們把上面方法里的修改后的js文件,生成一份與其引用路徑相同的目錄結構,放到站點文件里。就可以了。

這時,需要注意的一個問題是,swagger ui引用的swagger的js沒有擴展名, 而無擴展名的文件在瀏覽器里默認是不允許訪問的,所以,需要加mime類型,在iis里設置或在web.config里加配置均可(對於無后綴的文件,擴展名需填寫“.”符號,參考http://www.zhaomu.com/news/detail-393.html)。
<configuration>
<system.webServer>
<staticContent>
<mimeMap fileExtension="." mimeType="text/javascript" />
</staticContent>
</system.webServer>
</configuration>
