不用另外裝 COM 元件的 Classic ASP 檔案上傳

都 2012 年了還沒改用 .NET ,不但隔壁系同梯非常不以為然,就連自己也很意外會回頭寫 ASP… XD

幾乎所有教 ASP 的書在檔案上傳一節,都會要讀者加裝一支 COM 元件(大多是書籍作者自己寫的 xxxUpload 之類的 COM),再透過 CreateObject 帶進來解 multipart/form-data,於是寫一支 ASP 檔案上傳程式變得非常簡單。問題是,若用的是別人家的 Server,就得拜託幫忙裝 COM,而且人家還不一定會答應。

於是有人就想到拿 Request.BinaryRead 自己解整個 HTTP Request。網路上能找到很多寫得很 dirty 的範例,但大多只能上傳一個檔案,從 Header 撈檔名等等撈法也寫得不是很好。

最後找到的終極解是 Lewis Moten 寫的 Upload Files Without COM v3 (clsUpload)。除了支援多檔上傳,它幾乎把可能用到的東西都寫好包成一個 Class,也為沒辦法用 Request.Form 的問題解套。

筆記一下遇到的問題:

  1. 原來的 CStrU() 實作得不好,只處理 single byte ANSI character,對其他編碼是個災難。建議換成另一個版本:Multipart/form-data and UTF-8 in a ASP Classic application – Stack Overflow
  2. IIS 7.5 Content-Length 的問題:若將上傳的檔案存在資料庫,勢必會需要寫另一隻 ASP 從資料庫讀檔,然後再用 Response.BinaryWrite 丟出去。以前我們會自己送 Content-Length,但在 IIS 7.5 底下 call Response.BinaryWrite 時,IIS 會幫忙算 Content-Length,若我們的 ASP 程式也有用 Response.AddHeader 丟一份 Content-Length,就會整個爛掉。
    我不確定這是不是 IIS 7.5 的 Bug、或是實作上有改變,IIS 7.0 以前不會有這個問題。換個角度看,其實這個特性也頗貼心,至少不會發生自己算錯 Content-Length 的問題。
    這可以透過檢查 Request.ServerVariables(“SERVER_SOFTWARE”) 是否為 Microsoft-IIS/7.5 來解決。
  3. Client-side: 搭配 Plupload 來用應該很不錯… 需要另外做 JSON-RPC…
  4. (跟 clsUpload 無關的話題) 現在覺得用 GUID 之類的 identifier 來索引資料庫裏頭的檔案比起 auto increment 好很多,讓外人沒辦法踹數字亂抓檔案。參照:HOW TO: Create GUIDs by Using Active Server Pages in IISHow to generate a GUID in VBScript? – Stack Overflow
分類: ASP。這篇內容的永久連結

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。