当ブログでは以前にクラシックASPとVBScrptを使ってファイルをアップロードできるWebAPIのサンプルプログラムを紹介しましたが、
「アップロードできるならダウンロードもできないと」っと言うことで、今回は同じく「クラシックASP」と「VBScript」を使用してファイルをダウンロードできるWebAPIのサンプルプログラムを紹介します。
はじめに
ブラウザを使わずにインターネットを介してファイルをダウンロードする処理は、前回紹介したファイルのアップロード処理よりも実装が容易で、かつ実装方法も色々とあります。
極端な実装方法だと、ウェブサーバーの公開されているディレクトリにダウンロードさせたいファイルを置いて、クライアントはそのファイルまでのURLを何らかの方法で叩くだけでもダウンロードをさせることができます。
ただ、それだと誰でもダウンロードできてしまい、また、例えば特定の条件でダウンロードさせるファイルを切り替えるといった高度な機能を持たせることはできません。
そういった作り込みまで考えると、やはりサーバー側で何らかのプログラムを動かしてダウンロード処理を実装することになります。
そんなサーバー側の処理をわざわざクラシックASPで作る必要はあまり無い気もしますが、敢えて今回もクラシックASP+VBScriptの組み合わせで実装してみます。
作成するWebAPIの実装概要
- サーバー側処理では「クラシックASPとVBScript」を使用する。※BASP21は使わない
- ダウンロードするファイルはテキスト形式以外にも対応する。
- ダウンロードするファイルは日本語のファイル名にも対応する。
- クライアント側はVBScriptで作り、バッチ実行を可能とする。
- クライアントはPOSTメソッドでサーバー側にパラメータを送信し、パラメータを受け取ったサーバーはパラメータを元に処理をする。
- 認証などのセキュリティへの配慮はしていないので必要によって検討してください。
サンプルプログラム
当項では、サーバー側に配置するクラシックASPによるプログラムと、それを呼び出す為のVBScriptで作ったプログラムを紹介します。
サーバー側プログラム(クラシックASP)
サーバー側に配置するクラシックASPのプログラムを紹介します。
尚、当ASPファイルのファイル名は仮で「FileDownload.asp」とします。
<% Dim Parameter1 Dim TargetFileFullName Dim objFS Dim TargetFileName 'POSTされたパラメーターを受け取ります。' Parameter1 = Request.Form("param1") 'もしパラメーターがURIエンコードされているなら、FunctionのURI_Decodeで変換します。 'Parameter1 = URI_Decode(Request.Form("param1")) 'パラメーターが複数ある場合も同様にパラメーター名を指定して受け取ります。 'Parameter2 = Request.Form("param2") On Error Resume Next '渡されたパラメーターを元に、認証をしたり何らかの処理をする場合は以下で実装します。' ' ' ' ' 'クライアントに返す(ダウンロードさせる)ファイルのパスを指定します。' TargetFileFullName = "E:\DownloadedFiles\download_test.pdf" 'ファイル名をファイルフルパスから取得' Set objFS = Server.CreateObject("Scripting.FileSystemObject") TargetFileName = objFS.GetFileName(TargetFileFullName) Set objFS = Nothing 'ADODB.Streamストリームオブジェクトを生成します。' Set objStream = Server.CreateObject("ADODB.Stream") 'Streamオブジェクトを開きます。' objStream.Open 'Streamオブジェクトの位置を戻します。' objStream.Position = 0 'Streamオブジェクトに格納するデータのtypeを1:バイナリに指定します。' objStream.Type = 1 'Streamオブジェクトにファイルを読み込ませます。' objStream.LoadFromFile(TargetFileFullName) 'httpレスポンスのContentTypeを指定します。' Response.ContentType = "binary/octet-stream" 'URIエンコードしたファイル名をヘッダに格納します。' Response.AddHeader "HTTP_File-Name",URI_Encode(TargetFileName) 'httpレスポンスにStreamオブジェクトをセットしてクライアントに返します。' Response.BinaryWrite objStream.Read() 'Streamオブジェクトを閉じて破棄します。' objStream.Close Set objStream = Nothing 'URIエンコードされた文字列をデコードします。' '関数内部ではJScriptを使用しています。' Function URI_Decode(TargetString) Dim objSC Dim js Dim strDecodeURI Set objSC = CreateObject("ScriptControl") objSC.Language = "JScript" Set js = objSC.CodeObject strDecodeURI = js.decodeURI(TargetString) URI_Decode = strDecodeURI Set objSC = Nothing End Function '引数で渡された文字列をURIエンコードします。' '関数内部ではJScriptを使用しています。' Function URI_Encode(TargetString) Dim objSC Dim js Dim strEncodeURI Set objSC = CreateObject("ScriptControl") objSC.Language = "JScript" Set js = objSC.CodeObject strEncodeURI = js.EncodeURI(TargetString) URI_Encode = strEncodeURI Set objSC = Nothing End Function %>
処理解説
当プログラムでは、クライアントからパラメータがPOSTで渡されます。
渡されたパラメータの値によって、ダウンロードさせるファイルを変更したり、ダウンロード可否の認証をするような想定です。
サーバのEドライブには「DownloadedFiles」フォルダが作られており、IISの仮想ディレクトリ配下ではない非公開ディレクトリです。
そこに置いてあるファイルをダウンロードさせる処理になっています。
ダウンロードさせるファイルはbinary状態でStreamオブジェクトに格納してhttpレスポンスでクライアントに送信します。
httpヘッダ内にクライアントに送信するファイルのファイル名をセットしています。
ファイル名はURIエンコードをしており、日本語のファイル名でも送信できます。
もしクライアントからPOSTされたパラメータでも日本語が使われる可能性があるなら、「URI_Decode」関数でURIデコードも実施できます。
クライアント側プログラム(VBScript)
上記のASPファイルを実行する為のクライアント側プログラムを紹介します。
尚、当処理はVBScriptで作成していますが、httpを使ってPOSTしたりStreamが扱えれば他のプログラム言語にも置き換え可能です。※例えばVBAならURIデコードの処理だけ修正すればほぼコピペで動くと思います。
当VBSファイルのファイル名はなんでも結構です。
Option Explicit Call DownloadFile Sub DownloadFile() Dim TargetFileName Dim objHTTP Dim objStream Dim paramStr Dim retCd Dim Full_URL 'ASPファイルを設置しているURLを指定します。 Full_URL = "http://target_srv/api/FileDownload.asp" Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP") 'パラメータをPOSTする場合は以下でセットします。 paramStr = "param1=111" 'paramStr = "" 'パラメーターを複数渡したい場合は&(アンバサンド)で結合します。 'paramStr = "param1=111¶m2=222" 'httpの通信を開くメソッドとURL、非同期通信有無を指定します。 objHTTP.Open "POST", Full_URL, False 'リクエストヘッダーを指定します。 objHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" 'パラメーターをPOSTして送信します。 objHTTP.send paramStr 'リクエストステータスを受け取ります。 retCd = objHTTP.Status 'リクエストコードが200以外ならエラーとします。 If retCd <> 200 Then msgbox "error:" & retCd Else 'レスポンス内のヘッダからファイル名をURIデコードして取得します。 TargetFileName = URI_Decode(objHTTP.getResponseHeader("HTTP_File-Name")) 'ADODB.Streamオブジェクトを生成します。 Set objStream = CreateObject("ADODB.Stream") 'Streamオブジェクトを開きます。 objStream.Open 'Streamオブジェクトのtypeを1:バイナリーで指定します。 objStream.Type = 1 'httpのレスポンスをStreamオブジェクトに書き込みます。 objStream.Write objHTTP.responseBody 'Streamオブジェクト内のバイナリーデータを物理ファイルとして保存します。 objStream.SaveToFile "C:/DownloadFiles/" & TargetFileName ,2 'Streamオブジェクトを閉じます。 objStream.Close End If End Sub '引数の文字列をURIデコードします。 Function URI_Decode(TargetString) Dim objSC Dim js Dim strDecodeURI Set objSC = CreateObject("ScriptControl") objSC.Language = "JScript" Set js = objSC.CodeObject strDecodeURI = js.DecodeURI(TargetString) URI_Decode = strDecodeURI Set objSC = Nothing End Function
処理解説
Subルーチンの「DownloadFile」がメイン処理です。
あとはURIデコード用の関数も用意してあります。
httpリクエストをサーバーに投げる際のメソッドはPOSTを使用し、上記のプログラム例ではパラメータは一つですが、複数のパラメータを渡す際の記述方法もコメントアウトして記載しておいたので、状況に合わせて修正してください。
レスポンスで戻されたbinary状態のファイルをStreamオブジェクトに入れて、Streamオブジェクトを介して実ファイルとして保存しています。
httpヘッダ内に元のファイル名が入っているので、URIデコードしたうえで、保存時の物理ファイル名として使用しています。
最後に
今回はクラシックASPを使用したファイルのダウンロード用WebAPIの実装方法を紹介しました。
予想はしていましたが、前回記事にしたクラシックASPでファイルをアップロードするサンプルプログラムを紹介する投稿はあまりアクセス数が伸びなかったので、クラシックASPで実装するWebAPIはあまり需要はないのかも知れません・・・。
今回も同様にアクセス数はあまり見込めなさそうですが、それでもこの世の中のどこかで、クラシックASPでファイルのアップロードやダウンロードをさせるWebAPIを実装しないといけない状況に追い込まれている技術者が居るかも知れません。
クラシックASPで且つブラウザを使わないWebAPIとなると、2020年のインターネットではだいぶ情報も得難くなっているので、こんな記事でもどこかの誰かに役に立つこともあるだろうと信じて今回も記事にしました。
ここまで読んでいただきましてありがとうございました。
それでは皆さまごきげんよう。
↓レガシーなWebシステムでも最新のブラウザ「Edge」のIEモードで使えば動くんです。
是非以下の記事も読んでみてください。