[ホーム] [会社概要] [製品] [サポート]
[BASP21 Pro] [FAQ] [アプリケーションガイド] [ユーザガイド] [リファレンス] [サンプル]
[FTP オブジェクト] [ソケット オブジェクト]
English

BASP21 Pro アプリケーションガイド

BASP21 Proは、コンポーネントとして簡単にアプリケーションに組み込むことができます。
ここでは、BASP21 Proを利用したアプリケーション作成方法を説明します。

■ メールを送信するには

BASP21 Pro は、SMTPプロトコルでメールをSMTPサーバに送信します。 ここではメール送信の基礎知識からさまざまなメール送信方法の実際を解説します。

ここでは次のトピックを説明します。

■ SMTPプロトコル
簡単に SMTP(Simple Mail Transfer Protocol)プロトコルを説明します。 SMTPプロトコルは、メール・クライアントがメール・サーバーに メール送信を依頼するしくみのひとつで RFC821(August 1982)で仕様が定義されています。 インターネットの世界では SMTPが代表的なメール転送プロトコルです。

メール・クライアントは、Windows環境ではOutlookやBecky!などが有名な クライアント・ソフトウエアです。 メール・サーバーでSMTPプロトコルを実装しているものをSMTPサーバーと呼びます。 SMTPサーバーは、TCP/IP プロトコルで接続されたLAN内や遠隔のコンピュータで 動作するサーバー・ソフトウエアです。 UNIX/Linux 環境では sendmail や qmail が有名なSMTPサーバー・ソフトウエアです。 Windows 環境ではIISが動作するコンピュータ自身にSMTPサーバーがある場合もあります。

BASP21 Proのメール送信機能は、このメール・クライアント機能を実装しています。

SMTPサーバーは、通常TCP/IP ポート25番でリスニングしています。 BASP21 Proオブジェクトは、メール送信を依頼されるとSMTPサーバーの IPアドレスのポート25番に向けて winsock でコネクトします。 コネクトが成功すると SMTPプロトコルに従ってメールデータを送信します。 ここでサーバ名を間違えるとコネクトが失敗します。 サーバー名の確認は、コマンドプロンプトで 次のようにtelnetコマンドを使います。

telnet サーバ名 25
telnetコマンドでコネクトが成功しかつSMTPサーバからメッセージが表示されたら サーバ名が正しいことになります。

次にSMTPサーバとのやりとりを簡単に順番に示します。

1. SMTPサーバ名からIPアドレスをDNSで引く - IPアドレスを指定すれば省略可能
2. IPアドレスのポート25でTCPコネクト
3. HELO/EHLOコマンド用のドメイン名をクライアントのIPアドレスから引く
                                         - ドメイン名を指定すれば省略可能
4. メール・サーバの呼出し(HELO/EHLOコマンド)
5. 認証(SMTP AUTH) - オプション
6. 送信の準備(MAIL FROMコマンド)
7. 宛先の通知(RCPT TOコマンド)
8. 本文の送信(DATAコマンド)
9. 終了通知(QUITコマンド)
10. TCP切断
通常、SendMailメソッドは、上記の処理を一度だけ実行します。 メールキューを指定した場合、SendMailメソッドは、メールファイルを作成するだけです。 FlushMailメソッドは、メールキュー内のメールファイルの数だけ 上記の[6.送信の準備] から[8.本文の送信]までの処理を繰り返します。

メールサーバ名の代わりに IPアドレスを指定すると[1.のDNS処理]、かつドメイン名を指定すると [3.のDNS処理]がスキップされますので環境によっては高速になることがあります。

----------------- basp21p.ini -------------------------------------------
[honban]
server=myhost.basp21.com/192.168.1.200

SMTPコマンドの機能説明は、SMTPプロトコルの仕様書(RFC821)で参照できます。 SMTP AUTHが有効なSMTPサーバーの場合は、ユーザ名とパスワードを指定しないと 送信が許可されません。SMTP AUTHを含むメール送信の認証方式に関しては 次のセクションで説明します。

SendMail/FlushMailメソッドは、正確にはSMTPサーバーからのメールの受付け結果を返します。 従って、実際に相手先に届いたかどうかはその時点では判断できません。これは通常の メール・クライアントで送信した場合でも同じです。

SMTPサーバーは、クライアントからのSMTPコマンドに対して返答コード(3桁の数字)と 共にメッセージを返します。 SMTPコマンドおよび応答コードは、ログレコード に記録されますのでトラブル時に確認できます。 応答コードの先頭の数字で処理が正常かどうか判断できるようになっています。
コード説明
2xx 正常応答。
3xx 正常応答。次のデータが必要。
4xx メモリ不足など一時的なエラー。
5xx メールアドレス形式エラー、認証エラーなど永久的エラー。
メッセージは、通常英文のテキストでSMTPサーバー・ソフトウエアによって異なります。

■ SMTPサーバー認証機能
SMTPサーバーは、SPAM(ここでは勝手に外部からメールの中継に使われることの意味)対策として 以下の認証機能をサポートしているものがあります。 IPアドレス(またはドメイン名)による認証は、クライアント側のIPアドレスが プライベートアドレスや特定のIPアドレスなどの登録済みのIPアドレスならば 接続を許可するというものです。 この設定方法は、SMTPサーバー・ソフトウエアによって異なります。 このIPアドレスによる制限方法は、SMTPサーバーの機能ではなく他の ソフトウエア(inetdやtcpserver)で実現していることがあります。 この場合、SMTPサーバーにデータが渡る前に接続が拒否されるということになります。

POP Before SMTP(POP3認証)は、該当メール・サーバーに対してメール受信が 事前に成功すれば、一定時間内の同一IPアドレスからのメール送信機能を許可するものです。 geocitiesなどの無料メールサービスで使われていることがあります。 BASP21 Proでは、RcvMailメソッドを実行することでPOP3認証できます。 通常、メール数の通知コマンド(STAT) を実行するだけでかまいません。

最近ではSMTP AUTHと呼ばれる認証方式がサポートされています。 SMTP AUTHは、SMTPプロトコルのセッション中にユーザ名とパスワードを 送信して SMTPサーバーの認証を受ける方式です。 通常HELOコマンドでSMTPサーバーに挨拶しますが、SMTP AUTH認証を使う場合は、 EHLOコマンドが使われます。 ほとんどの場合、ユーザ名とパスワードは、該当メール・サーバーのメールアカウント名と パスワードです。 ユーザ名とパスワードを送信する代表的な方法として BASE64 で送信する "LOGIN" と MD5 でハッシュして 送信する"CRAM-MD5" の2つがあります。

BASP21 Proは、"LOGIN" と"CRAM-MD5" 方式いずれもサポートしています。 BASP21 ProでSMTP AUTH機能を使うには、MailFromプロパティ のメール送信元アドレスの後に "," (カンマ)で区切って ユーザ名 + ":" + パスワード + "," +"login|cram-md5" を指定します。

bobj.MailFrom = "guest@basp21.com,user1:pass1"  ' 方式を省略するとLOGINになります
bobj.MailFrom = "guest@basp21.com,user1:pass1,cram-md5"
■ SMTPS(SMTP over SSL)機能
SMTPS(SMTP over SSL)機能は、メールサーバーまでのメールデータをSSL暗号化して 送信する機能です。
BASP21 ProでSMTPS(SMTP over SSL)機能を使うには、Serverプロパティ でメールサーバー名の前に"SSL "文字列を指定するSTARTTLSコマンド方式とポート番号465を 使う方法の2つのいずれかを選択します。

お使いのメールサーバーのSSL通信方式によって、この2つの方式を適切に選択して使う必要があります。
bobj.Server = "SSL hosta"  ' STARTTLSコマンド方式。通常ポート番号25
' または
bobj.Server = "hosta:465"  ' smtpsポート。465固定。
■ メールアドレス
BASP21 Proで扱うメールアドレスは、次のような形式です。
guest@basp21.com
<guest@basp21.com>
任意の名前<guest@basp21.com>
guest@basp21.com(任意の名前)
任意の名前は、SMTPサーバの動作には影響を及ぼしませんが、 メール・クライアントが表示用に使いますのでつけたほうがいいでしょう。

任意の名前は、日本語も使えますが、日本語を表示できないメール・クライアントではもちろん 文字化けしますので注意しましょう。

複数の宛先メールアドレスを指定するには "," で区切ります。 任意の名前の中に "," を含めないでください。

mailto = "guest@basp21.com,ゲスト2<guest2@basp21.com>"
■ メールヘッダー
メールヘッダーは、メール本文の前につく情報です。
ヘッダー種類説明
Received 通過したメールサーバーのタイムスタンプ
Message-ID インターネット上で一意に識別するためのID
Date 送信した日時。タイムゾーン情報も入ります
From 送信した人のメールアドレス
To 受信した人のメールアドレス
Cc 送信時にコピーが送信された人のメールアドレス
Reply-To 受信した人に伝える返信先のメールアドレス
Subject 件名
Content-Transfer-Encoding 符号化方式
Content-Type 本文のファイル形式やコードの種類。
X-Mailer メール・クライアント名
X-Mail-Agent メール・クライアント名。BASP21 Proではこのヘッダを送信します。
X-がつくヘッダーは、SMTPプロトコルでは規定されていないオプションヘッダーです。
■ メール送信のためのBASP21P.INI設定
メール送信のためのBASP21P.INI設定方法を説明します。 以下は、メール送信処理の既定値を設定するBASP21P.INIファイル例です。
----------------- basp21p.ini -------------------------------------------
[test]
server=smtp-server
mailfrom=your@basp21.com
mailoption=cc,hoge@basp21.com,hoge2@basp21.com,bcc,hoge3@basp21.com
[honban]
server=hosta/192.168.1.200
mailfrom=your@basp21.com,user1:pass1
mailoption=cc,hoge@basp21.com,>Reply-To: me@basp21.com
Envがtest環境の場合、SMTPサーバは、smtp-server が選択されます。 送信元メールアドレスは、your@basp21.com が使われます。
bobj.Env = "test"
bobj.SendMail mailto,subj,body,files

Envがhonban環境の場合、SMTPサーバは、192.168.1.200 が選択されます。 "/" で区切られた前の名前は、ドメイン名としてSMTPプロトコルで HELO コマンドで使われます。

bobj.Env = "honban"
bobj.SendMail mailto,subj,body,files

また、以下のようにスクリプト内でダイナミックにSMTPサーバ名と送信元メール アドレスを指定することもできます。

bobj.Env = "honban"
bobj.Server = "hosta/192.168.1.200"
bobj.MailFrom = "your@basp21.com,user1:pass1"
bobj.MailOption = "cc,hoge@basp21.com,>Reply-To: me@basp21.com"
bobj.SendMail mailto,subj,body,files
■ メールキュー
メールキューは、メール送信データを格納するディレクトリです。 MailQueueプロパティで指定します。 mailqueueパラメータは、 MailQueueプロパティの既定値です。 SendMailメソッドは、MailQueueプロパティに ディレクトリ名の指定があれば、SMTPサーバーにはメールを送信せずにメールキューに メールファイルを作成するだけで終了します。

メールファイルは、メールアドレスとメールオプションの形式チェックの後、 エンコードされずにShift JIS コードで作成されます。 MailOptionプロパティの内容も このときに参照されて書込まれます。 SMTPサーバー名はメールファイルに格納しません。 メールファイルは、以下のような形式です。

1行目:送信先メールアドレス + ヘッダーなどのメールオプション
2行目:送信元メールアドレス + SMTP AUTHパラメータ(オプション)
3行目:件名
4行目:添付ファイル名
5行目以降:本文
メールファイルは、ReadMailメソッドで 内容を確認できます。 メールキューは、mailqueueパラメータを指定すると BASP21 Proが自動的に 作成します。作成するときにerr サブディレクトリとsent サブディレクトリも同時に 作成します。例えば、次のようにBASP21P.INI ファイルで定義した場合:
----------------- basp21p.ini -------------------------------------------
[iis5]
home=c:\test\env1
mailqueue=.mailqueue
以下の3つのディレクトリが作成されます。
c:\test\env1\mailqueue
c:\test\env1\mailqueue\err
c:\test\env1\mailqueue\sent
メールキューに作成したメールファイルは、FlushMailメソッド で実際にSMTPサーバーに送信します。
■ ASPでのメール送信(SendMailメソッド)
SendMailメソッド実行時にMailQueueプロパティにディレクトリ名の指定がない場合は、 SMTPサーバーにメールを送信します。 次に一般的なHTMLフォームから起動するSendMailメソッドを使うメール送信の スクリプトを示します。
================ sendm01.asp ============================================
<html><head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<title>SendMail Testing Page</title></head>
<body>
<%
set bobj = Server.CreateObject("basp21pro")
bobj.Env = "iis5:" & Request.ServerVariables("REMOTE_ADDR")
mailto=Request.Form("name")
subj=Request.Form("subj") & now()
comment=Request.Form("comment")
bobj.MailQueue=""
rc = bobj.SendMail(mailto,subj,comment)
If bobj.IsError Then
   rc = bobj.LastMsg
End If
set bobj = Nothing
%>
rc=<% = rc %><br>
name=<% = name %><br>
subj=<% = subj %><br>
<pre>
comment=<% = comment %>
</pre>
<p></body></html>
sendm1.asp は、以下のHTMLファイルから起動します。
================ sendm01.html ============================================
<HTML><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<TITLE>SendMail Testing Page</TITLE></HEAD>
<BODY>
<FORM ACTION=sendm1.asp METHOD=POST>
name:<INPUT TYPE=TEXT name=name><BR>
subj:<INPUT TYPE=TEXT name=subj><BR>
comment:<TEXTAREA name=comment rows=5 cols=50></TEXTAREA><BR>
<INPUT TYPE=SUBMIT name=SUBMIT value=GO!!!!>
</FORM>
</BODY></HTML>
BASP21P.INIファイルは、以下のように指定します。
----------------- basp21p.ini -------------------------------------------
[global]
allow=env
[iis5]
allow=sendmail
server=smtp-server
mailfrom=hoge@basp21.com
home=c:\basp21p\iis5
logfile=.\log.txt
logfilerotate=1024
IISでのメール送信回数が多い場合は、SMTPサーバーの接続・切断処理が連続して発生するため 回線やSMTPサーバーに負荷がかかることがあります。 その場合には、メールキューを使ってのFlushMailメソッド による一括送信を検討してください。
■ ASP.NETでのメール送信(SendMailメソッド)
SendMailメソッド実行時にMailQueueプロパティにディレクトリ名の指定がない場合は、 SMTPサーバーにメールを送信します。 次にASP.NETでの一般的なHTMLフォームから起動するSendMailメソッドを使うメール送信の サンプルを示します。
================ sendm01vb.aspx ============================================
<%@ PAGE validateRequest="false" %> 
<%@ Assembly name="BASP21PROLib" %>
<%@ Import namespace="BASP21PROLib" %>
<html><head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<script language="vb" runat="server">
Sub Page_Load(Sender As Object, e As EventArgs)
 If  not IsPostBack Then
    name.Value = ""
    subject.Value = ""
    comment.Value = ""
 End If
End Sub
Sub submit_click(Sender As Object, e As EventArgs)
  Dim bobj As basp21p
  Dim mailto As String,subj As String,body As String,files As String
  Dim rc As long
  bobj = new basp21p()
  bobj.Env = "iis6"
  mailto = name.Value
  subj = subject.Value
  body = comment.Value
  files = ""
  bobj.Mailqueue = ""
  rc = bobj.SendMail(mailto,subj,body,files)
  Message.innerText = "Done. " & CStr(rc)
End Sub
</script>
</head>
<body>
  <form runat="server">
   name:<input type=text id="name" runat="server"><BR>
   subject:<input type=text id="subject" runat="server"><BR>
   comment<textarea id="comment" cols=40 rows=4 runat="server" />
   <input type=submit value="Submit" 
             OnServerClick="submit_click" runat="server">
  </form>
  <B><span id="Message" runat=server></span></B>
</body>
</html>
C#では以下のようになります。
================ sendm01c.aspx ============================================
<%@ PAGE validateRequest="false" %> 
<%@ Assembly name="BASP21PROLib" %>
<%@ Import namespace="BASP21PROLib" %>
<html><head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<script language="C#" runat="server">
void Page_Load(object sender, EventArgs e)
{
 if (!IsPostBack)
  {
    name.Value = "";
    subject.Value = "";
    comment.Value = "";
  }
}
void submit_click(object sender, EventArgs e)
{
  basp21p bobj;
  string mailto,subj,body,files;
  int rc;
  bobj = new basp21p();
  bobj.Env = "iis6";
  mailto = name.Value;
  subj = subject.Value;
  body = comment.Value;
  files = "";
  bobj.MailQueue = "";
  rc = bobj.SendMail(mailto,subj,body,files);
  Message.InnerText = "Done. " + rc.ToString();
}
</script>
</head>
<body>
  <form runat="server">
   name:<input type=text id="name" runat="server"><BR>
   subject:<input type=text id="subject" runat="server"><BR>
   comment<textarea id="comment" cols=40 rows=4 runat="server" />
   <input type=submit value="Submit" 
             OnServerClick="submit_click" runat="server">
  </form>
  <B><span id="Message" runat=server></span></B>
</body>
</html>
BASP21P.INIファイルは、以下のように指定します。
----------------- basp21p.ini -------------------------------------------
[global]
allow=env
[iis6]
allow=all
server=smtp-server
mailfrom=hoge@basp21.com
home=c:\basp21p\iis6
logfile=.\log.txt
logfilerotate=1024
■ 一括メール送信(FlushMailメソッド)
メールキューに格納されたメールファイルを送信するには、 FlushMailメソッドを使います。 以下は、FlushMailメソッドを使うメール送信のスクリプトです。
----------------- sendm02.asp -------------------------------------------
<html><head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<title>SendMail Testing Page</title></head>
<body>
<%
set bobj = Server.CreateObject("basp21pro")
bobj.Env = "iis5:" & Request.ServerVariables("REMOTE_ADDR")
If Not IsRun("FlushMail") Then
  rc = bobj.FlushMail
  If bobj.IsError Then
     rc = bobj.LastMsg
  End If
Else
  rc = "FlushMail busy"
End If
set bobj = Nothing
Function IsRun(method)    ' Monitor メソッドで実行中のメソッドを調べる
 IsRun = 0
 ar = bobj.Monitor(1)
 If bobj.Result <= 0 Then Exit Function
 For Each ret in ar
   If InStr(ret,method) > 0 Then 
     IsRun = 1
     Exit Function
   End If
 Next
End Function
%>
rc=<% = rc %><br>
</pre>
<p></body></html>
JScriptのサンプルです。
----------------- jsendm02.asp -------------------------------------------
<html><head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<title>SendMail Testing Page</title></head>
<body>
<%
var bobj,rc;
bobj = Server.CreateObject("basp21pro");
bobj.Env = "iis5:" & Request.ServerVariables("REMOTE_ADDR");
if (IsRun("FlushMail") == 0) {
  rc = bobj.FlushMail();
  if (bobj.IsError == 1)rc = bobj.LastMsg;
} else
  rc = "FlushMail busy";
function IsRun(method)
{
 var vbarray,ar,ret,taskno;
 vbarray = bobj.Monitor(1);
 if (bobj.Result <= 0) return 0;
 taskno = bobj.Result;
 ar = vbarray.toArray();
 var i;
 for (i = 0; i < taskno; i++) {
   if (ar[i].indexOf(method) != -1) return 1;
 }
 return 0;
}
%>
rc=<% = rc %><br>
</pre>
<p></body></html>
FlushMailメソッドは、メソッド開始時にメールキューに存在するメールファイルのリストを 作成します。FlusuMailメソッドは、作成したファイルのリストを参照して送信します。 リスト作成後に SendMailメソッドでメールキューに追加されたメールファイルは送信しません。

正常にSMTPサーバーに送信されたメールファイルは、メールキューから削除されます。 メールキューに sent サブディレクトリが存在する場合は、メールキューから 該当メールファイルの処理終了後に移動します。

何らかの理由で送信されなかったメールファイルは、メールキューに残ります。 メールキューに err サブディレクトリが存在する場合は、メールキューから 該当メールファイルの処理終了後に移動します。

同一のメールキューでFlushMailメソッドが実行中の場合は、2回目以降のFlushMailメソッドは 失敗します。
Monitorメソッドを使ってFlushMailメソッドが 既に実行されているか確認したほうがいいでしょう。

■ プロセスを分離して送信
BASP21 Proには、メソッドを別プロセスで実行する以下の機能があります。 BHELPER.EXEは、BASP21 Proオブジェクトをラップした Win32アプリケーションです。 Windows のATコマンドとBHELPER.EXE を組合わせて使うと、 BASP21 Proメソッドをスケジュールして実行することができます。 次の例は、毎週金曜日の18:00にFlushMailメソッド をATコマンドで実行します。
at 18:00 /every: f /interactive c:\b21pro\bhelper -e env1 flushmail
Processメソッドは、指定したメソッドを別プロセスで実行します。 次の例は、送信メールキューが20通になったらFlushMailメソッドを別プロセスで実行する VBScriptのサンプルです。
----------------- sendm03.asp -------------------------------------------
<html><head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<title>BASP21 Pro Page</title></head>
<body>
<%
set bobj = Server.CreateObject("basp21pro")
bobj.Env ="env1:test1.asp"
name=Request.Form("name")
subj=Request.Form("subj")
comment=name & vbCrLf & Request.Form("comment")
mailto="g1<hoge@basp21.com>"
rc = bobj.SendMail(mailto,subj,comment)
If Not bobj.IsError Then
   msg = "mail queueing...."
   call CheckFlushMail
Else
   msg = bobj.LastMsg
End If
Sub CheckFlushMail
  mailcount = bobj.FileCheck(bobj.MailQueue,1)
  If 20 < mailcount Then
    If IsRun("FlushMail") = 0 Then
       rc = bobj.Process("-e env1 FlushMail")
       msg = "FlushMail Start ... " & mailcount & " threadid=" & rc
    Else
      msg = "FlushMail Running..."
   End If
  End If
End Sub 
Function IsRun(method)    ' Monitor メソッドで実行中のメソッドを調べる
  IsRun = 0
  ar = bobj.Monitor(1)
  If bobj.Result <= 0 Then Exit Function
  For Each ret in ar
    If InStr(ret,method) > 0 Then 
      IsRun = 1
      Exit Function
    End If
  Next
End Function
%>
msg=<% = msg %><br>
rc=<% = rc %><br>
name=<% = name %><br>
subj=<% = subj %><br>
<pre>
comment=<% = comment %>
</pre>
<p></body></html>
JScriptのサンプルです。
----------------- jsendm03.asp -------------------------------------------
<%@ LANGUAGE="JavaScript" %>
<html><head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<title>BASP21 Pro Page</title></head>
<body>
<%
var bobj,msg;
bobj = Server.CreateObject("basp21pro");
bobj.Env ="env1:jtest1.asp";
var name = Request.Form("name");
var subj = Request.Form("subj");
var comment = name + unescape("%0D%0A") + Request.Form("comment");
var mailto = "g1<hoge@basp21.com>";
var rc = bobj.SendMail(mailto,subj,comment);
if (!bobj.IsError) {
   msg = "mail queueing....";
   CheckFlushMail();
} else {
   msg = bobj.LastMsg;
}
function CheckFlushMail()
{
  var mailcount,rc;
  mailcount = bobj.FileCheck(bobj.MailQueue,1);
  if (20 < mailcount) {
    if (IsRun("FlushMail") == 0) {
       rc = bobj.Process("-e env1 FlushMail");
       msg = "FlushMail Start ... " + mailcount + " threadid=" + rc;
    } else {
      msg = "FlushMail Running...";
    }
  }
}
function IsRun(method) // Monitor メソッドで実行中のメソッドを調べる
{
 var vbarray,ar,ret,taskno;
 vbarray = bobj.Monitor(1);
 if (bobj.Result <= 0) return 0;
 taskno = bobj.Result;
 ar = vbarray.toArray();
 var i;
 for (i = 0; i < taskno; i++) {
   if (ar[i].indexOf(method) != -1) return 1;
 }
 return 0;
}
%>
msg=<% = msg %><br>
rc=<% = rc %><br>
name=<% = name %><br>
subj=<% = subj %><br>
<pre>
comment=<% = comment %>
</pre>
<p></body></html>
■ Cc/Bcc の使い方
メール送信時にCc/Bcc ヘッダーを追加して送信するには宛先の後にカンマで 区切って指定します。
mailto = Request.Form("name")
mailto = mailto & ",cc,hoge2<hoge2@basp21.com>,hoge3<hoge3@basp21.com>"
mailto = mailto & ",bcc,hoge4<hoge4@basp21.com>,hoge5<hoge5@basp21.com>"
rc = bobj.SendMail(mailto,subj,comment)
また、MailOptionプロパティでも指定できます。
mailto = Request.Form("name")
bobj.MailOption = "cc,hoge2<hoge2@basp21.com>,hoge3<hoge3@basp21.com>" & _
 ",bcc,hoge4<hoge4@basp21.com>,hoge5<hoge5@basp21.com>"
MailOptionプロパティの既定値は、 mailoptionパラメータで設定できます。
■ 件名や本文の指定
メールの件名は、SendMailメソッドの第2パラメータで指定します。 件名は、日本語を指定できます。件名には改行コードは指定できません。 件名の最大サイズは、BASP21 Proの仕様上では無制限ですがSMTPプロトコル上、 1行の長さが800バイト程度に制限されています。
subject = "会議のお知らせ"
bobj.SendMail mailto,subject,body
メールの本文は、SendMailメソッドの第3パラメータで指定します。 改行コードは、CR(13) + LF(10) で指定します。CR のみや LF のみを指定した場合は CR + LF に変換してSMTPサーバーに送信します。
1行の長さは、800 バイト以内とSMTPプロトコルで規定されています。 1行の長さが大きいと日本語の場合、メールクライアントで文字化けしたりします。
body = "こんにちは" & vbCrLf & "さようなら" 
件名や本文の半角カナは、全角カナに変換して送信します。
本文の最大サイズは、BASP21 Proの仕様上では無制限です。 1行の最大サイズは、BASP21 Proの仕様では 800 バイト以内です。

SMTPプロトコルでは、通常データは7bit で送信します。 ヘッダーに日本語が指定されている場合は、JISコードに変換してさらに BASE64でエンコードします。本文に日本語が含まれている場合は、JISコードに変換します。 添付ファイルは、BASE64でエンコードして MIME boundary 文字列で区切られて本文の後に 送信されます。

■ 添付ファイルの指定
添付ファイルは、SendMailメソッドの4番目のパラメータとして指定します。 添付ファイルがない場合は省略可能なパラメータです。
files = "c:\temp\abc.doc"
rc = bobj.SendMail(mailto,subj,comment,files)
複数のファイルを指定するには "," カンマで区切ります。
files = "c:\temp\abc.doc,c:\temp\abc.jpg,c:\temp\abc.txt"
rc = bobj.SendMail(mailto,subj,comment,files)
オプションとしてファイル名の後に"|"で区切って別名やMIMEのContent-Type、Content-IDを 指定できます。実際のファイル名とは別の名前で送信したいときに別名を使います。
files="パス名[|別名[|Content-type[|Content-ID]]]"
files="c:\temp\aa.txt|abc.txt" ' 別名指定
files="c:\temp\aa.txt||application/octet-stream" ' Content-type 指定
files="c:\temp\aa.txt|abc.txt|application/octet-stream" ' 別名+Content-type 指定
files="c:\temp\good.jpg|||goodjpeg" ' Content-ID 指定
Content-type は、メール・クライアントが添付ファイルを受信したときに参照します。
Content-IDは、HTMLメールで添付ファイルを本文から参照するときに使います。
bobj.MailOption = ">Content-Type: text/html; charset=iso-2022-jp"
body = "<HTML><BODY><IMG SRC=cid:goodjpeg>" & vbCrLf & _
    "</BODY></HTML>"
files = "c:\temp\good.jpg|||goodjpeg"
rc = bobj.SendMail(mailto,subj,body,files)

Content-type を省略するとファイルの拡張子によりContent-Typeが次のように設定されます。
拡張子Content-type
txttext/plain
htm htmltext/html
jpg jpegimage/jpeg
gifimage/gif
bmpimage/bmp
zipapplication/x-zip-compressed
docapplication/msword
xlsapplication/vnd.ms-excel
pptapplication/vnd.ms-excel
xlsapplication/vnd.ms-powerpoint
exe dllapplication/vnd.ms-download
eml mht mhtml nwsmessage/rfc822
fdfapplication/vnd.fdf
pdfapplication/pdf
rmiaudio/mid
qt movvideo/quicktime
avivideo/x-msvideo
tiffimage/tiff
wav mp1 mp2 mp3audio/wav
alsAudio/X-Alpha5
以外application/octet-stream
■ その他のヘッダーの指定
任意のヘッダーを追加して送信するには、 MailOptionプロパティに指定します。 ">"をつけたデータは、ヘッダーとして送信します。 例えばエラーの場合にSMTPサーバーから通知を受けたい場合は、Return-Pathヘッダーを 使います。
bobj.MailOption = ">Return-Path: <admin@basp21.com>"
Disposition-Notification-Toヘッダーは、相手のメーラーが対応していれば 相手が開封したときに開封確認のメールを 返信してくれます。
bobj.MailOption = ">Disposition-Notification-To: <admin@basp21.com>"
HTML形式でメールを出したい場合は、Content-Typeヘッダーを使います。
bobj.MailOption = ">Content-Type: text/html; charset=iso-2022-jp"
MailOptionプロパティの既定値は、 mailoptionパラメータで設定できます。
----------------- basp21p.ini -------------------------------------------
[iis5]
mailoption=>Return-Path: <admin@basp21.com>,
    [改行してます]    >Disposition-Notification-To: <admin@basp21.com>
■ SendMailメソッドの認証機能を使うには
BASP21 Proで認証機能を使うには、MailFromプロパティ のメール送信元アドレスの後に "," (カンマ)で区切って ユーザ名 + ":" + パスワード + "," +"login|cram-md5" を指定します。
bobj.MailFrom = "guest@basp21.com,user1:pass1"  ' 方式を省略するとLOGINになります
bobj.MailFrom = "guest@basp21.com,user1:pass1,cram-md5"
BASP21P.INIファイルのmailfromパラメータ は、MailFromプロパティの既定値です。
----------------- basp21p.ini -------------------------------------------
[iis5]
allow=sendmail,flushmail
mailfrom=guest@basp21.com,user1:pass1
■ POP Before SMTPを使うには
POP Before SMTPとは、メールを送信する前にメール受信処理をしないと、 メール送信を許可しない SMTPサーバーの認証機能または実装のことです。 SPAM(迷惑メール)の中継を禁止する目的でプロバイダなどで広く導入されている機能です BASP21 ProでPOP Before SMTPを使うには、SendMailメソッドまたはFlushMailメソッドなどで SMTPサーバーにコネクトする前に、RcvMailメソッドを呼出すだけです。
bobj.RcvMail "","","stat"
bobj.FlushMail
RcvMailメソッドが成功してから一定時間(10分程度)は、メール送信が許可されます。
■ 中継(Relay)エラーメッセージ一覧
以下のようなSMTPサーバーからのメッセージは、中継エラーでメール送信をSMTPサーバーが 拒否したことを示します。
550 Relaying is prohibited to xxxxxx
550 5.7.1 Unable to relay for xxxxxx
550 xxxxxxxxxxx Relaying denied to xxxx
550 relaying mail to xxxx is not allowed to xxxxx
550 Unable to relay for xxxxxx
553 xxxx... Relay operation rejected
571 Relay operation rejected xxxxxxxxxx
572 Relay not authorized 
中継エラーの場合は、 SendMailメソッドの認証機能または POP Before SMTPを使って メールの送信を試みてください。

■ メールを受信するには

BASP21 Pro は、RcvMailメソッドを使って POP3プロトコルでメール・サーバーからメールを受信します。 ここではメール受信の基礎知識からアプリケーションでのメール受信方法の 実際を解説します。

ここでは次のトピックを説明します。

■ POP3プロトコル
POP3(Post Office Protocol version 3)プロトコルは、メール・クライアントが メール・サーバーからメールを受信する手順です。 POP3は、RFC1939番で仕様が定義されています。 POP3の手順は、SMTPと同様にコマンドと応答コードのやりとりです。
1. POP3サーバ名からIPアドレスをDNSで引く - IPアドレスを指定すれば省略可能
2. IPアドレスのポート110番でTCPコネクト
3. ユーザー認証(USERコマンド、PASSコマンド)
4. メール・ボックスの内容確認(STATコマンド)
5. 1通ごと受け取る(RETRコマンド)
6. 削除依頼(DELEコマンド)
7. 終了通知(QUITコマンド)
8. TCP切断
[4.] から[6.] までのPOP3コマンド処理は、RcvMailメソッドのコマンドによって指定します。

POP3サーバーは、クライアントからのPOP3コマンドに対して返答コードと 共にメッセージを返します。 POP3コマンドおよび応答コードは、ログレコード に記録されますのでトラブル時に詳細なやりとりを確認できます。
POP3コマンド説明
STAT メール・ボックスのメール数とサイズの取得。
LIST メールサイズの取得。
RETR 指定したメールの取得。
DELE 指定したメールの削除。
TOP 指定したメッセージヘッダーと本文の指定行の取得。
UIDL メールのIDを取得。
USER ユーザ認証時のユーザ名送信。
PASS ユーザ認証時のパスワード送信。
APOP MD5で暗号化されたユーザ認証の送信。

応答コードの先頭の文字が "+" か "-" かで処理が正常かどうか判断できるようになっています。 POP3応答を次に示します。
POP3応答説明
+OK xxx 正常応答。
-xxxxx 何らかのエラー。
メッセージは、通常英文のテキストでPOP3サーバー・ソフトウエアによって異なります。

■ POP3S(POP3 over SSL)機能
POP3S(POP3 over SSL)機能は、メールサーバーからメールデータをSSL暗号化して 受信する機能です。
BASP21 ProでPOP3S(POP3 over SSL)機能を使うには、PopServerプロパティ でメールサーバー名の前に"SSL "文字列を指定するSTLSコマンド方式とポート番号995を 使う方法の2つのいずれかを選択します。
Gmailは、SSL対応ですので POP3Sを使用する必要があります。

お使いのメールサーバーのSSL通信方式によって、この2つの方式を適切に選択して使う必要があります。
bobj.PopServer = "SSL hosta"  ' STLSコマンド方式。通常ポート番号110
' または
bobj.PopServer = "hosta:995"  ' pop3sポート。995固定。
bobj.PopServer = "pop.gmail.com:995"  ' Gmail の場合
■ ユーザの認証
POP3プロトコルには、ユーザの認証の仕組みが提供されています。 userコマンドでユーザ名を送信して pass コマンドでパスワードを送信します。 デフォルトではユーザ名とパスワードは、平文でネットワーク上を流れます。 ユーザ名とパスワードは、RcvMailメソッド のパラメータで指定します。
  rc = bobj.RcvMail("user1","pass1","stat")
ユーザ名とパスワードの既定値は、mailuserpassパラメータ で指定可能です。RcvMailメソッドでNULL を指定するとmailuserpassパラメータを 使います。
  rc = bobj.RcvMail("","","stat")

最近ではAPOP認証と呼ばれるパスワードを暗号化して送信する方式がメール・サーバーで サポートされています。 BASP21 Proは、このAPOP認証もサポートしています。 パスワードの前に"A " を指定するとAPOP認証を試みます。

  rc = bobj.RcvMail("user1","A pass1","stat")
■ メールボックスの内容確認
ユーザに対応したメールボックスの内容を確認するには、STATコマンドを使います。
ar = bobj.RcvMail("user1","pass1","stat")
mail_count = bobj.Result
If mail_count > 0 Then
   temp = Split(ar(0)," ")
   mail_size = temp(1)
End If
サーバに保存されているメール数がResultプロパティに設定されます。 正常終了した場合は、戻り値として配列変数でメール数 + " " + バイト数が返ります。
ASP.NETを使用した場合は、以下のようになります。
<%@ PAGE validateRequest="false" %> 
<%@ Assembly name="BASP21PROLib" %>
<%@ Import namespace="BASP21PROLib" %>
<html><head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<script language="vb" runat="server">
Sub Page_Load(Sender As Object, e As EventArgs)
 If  not IsPostBack Then
    name.Value = ""
    pass.Value = ""
 End If
End Sub
Sub submit_click(Sender As Object, e As EventArgs)
  Dim bobj As basp21p
  Dim ar As Object, temp As Object
  Dim rc As Long,mail_count As Long, mail_size As String
  bobj = new basp21p()
  bobj.Env = "iis6"
  ar = bobj.RcvMail(name.Value,pass.Value,"stat")
  mail_count = bobj.Result
  If mail_count > 0 Then
    temp = Split(ar(0)," ")
    mail_size = temp(1)
  End If
  Message.innerText = "Done. count=" & CStr(mail_count) & " size=" & CStr(mail_size)
End Sub
</script>
</head>
<body>
  <form runat="server">
   name:<input type=text id="name" runat="server"><BR>
   pass:<input type=password id="pass" runat="server"><BR>
   <input type=submit value="Submit" 
             OnServerClick="submit_click" runat="server">
  </form>
  <B><span id="Message" runat=server></span></B>
</body>
</html>
C#の場合は、以下のようになります。
<%@ PAGE validateRequest="false" %> 
<%@ Assembly name="BASP21PROLib" %>
<%@ Import namespace="BASP21PROLib" %>
<html><head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<script language="C#" runat="server">
void Page_Load(object sender, EventArgs e)
{
 if (!IsPostBack)
  {
    name.Value = "";
    pass.Value = "";
  }
}
void submit_click(object sender, EventArgs e)
{
  basp21p bobj;
  object ar;
  string mail_size;
  int rc,mail_count;
  bobj = new basp21p();
  bobj.Env = "iis6";
  ar = bobj.RcvMail(name.Value,pass.Value,"stat","");
  mail_count = bobj.Result;
  mail_size = "";
  if (mail_count > 0)
   {
    string[] temp = new string[1];
    Array.Copy((Array)ar,temp,1);
    string ret = temp[0];
    mail_size = ret.Split(new Char[] {' '})[1];
  }
  Message.InnerText = "Done. count=" + mail_count.ToString() + " size=" + mail_size;
}
</script>
</head>
<body>
  <form runat="server">
   name:<input type=text id="name" runat="server"><BR>
   pass:<input type=password id="pass" runat="server"><BR>
   <input type=submit value="Submit" 
             OnServerClick="submit_click" runat="server">
  </form>
  <B><span id="Message" runat=server></span></B>
</body>
</html>

■ メール受信

メールを受信するには次の受信系のRcvMailメソッドのコマンドを指定します。
RcvMailコマンド説明
SAVENEW 新着メールを受信。
SAVENEWD 新着メールを受信。 受信後にサーバーから受信したメールを削除。
SAVEALL すべてのメールを受信。一度に8192通まで受信。
SAVEALLD すべてのメールを受信。一度に8192通まで受信。 受信後にサーバーから受信したメールを削除。
SAVE n[-n2] 指定したメール番号のメールを受信。
SAVD n[-n2] 指定したメール番号のメールを受信。 受信後にサーバーからメールを削除。

受信系のコマンド発行時のRcvMailメソッドの戻り値は、受信したメールを格納した ファイル名が配列で返ります。
Resultプロパティに受信したメール数が設定されます。

ar = bobj.RcvMail("user1","pass1","SAVENEW",bobj.MailBox & "\new")
mail_count = bobj.Result

他のRcvMailメソッドのコマンドは次のとおりです。
RcvMailコマンド説明
LIST [n[-n2]] n番目からn2番目までのメール番号に対応するメールのSubject、From、Dateヘッダーの 内容のみを返します。 nとn2を省略するとすべて(8192まで)読込みます。
SIZE [n[-n2]] n番目からn2番目までのメール番号に対応するメールのサイズを返します。 n2を省略するとn番目のメールのみ、nとn2を省略するとすべて(8192まで)のメールが 対象となります。 "n ssss" のように最初にメール番号、空白をおいてサイズを返します。
UIDL [n[-n2]] n番目からn2番目までのメール番号に対応するメールのUIDLを返します。 n2を省略するとn番目のメールのみ、nとn2を省略するとすべて(8192まで)のメールが 対象となります。 "n uuuu" のように最初にメール番号、空白をおいてUIDLを返します。
DELE [n[-n2]] n番目からn2番目までのメール番号に対応するメールをサーバーから削除します。 n2を省略するとn番目のメールのみ、nとn2を省略するとすべて(8192まで)のメールが 対象となります。
DELU UIDLX[,uildx,...] 指定したUIDLXのメールをサーバーから削除します。 UIDLX は、カンマで区切って 一度に8192 まで指定できます。

■ 受信ファイル形式(RFC822)
RcvMailメソッドは、サーバーから受信したメール内容を1通ごとに変更せずにそのまま 保存します。 この保存されたファイルは、RFC822と呼ばれる仕様のテキストファイルです。 RFC822ファイルは、次のようなフォーマットです。ヘッダーと本文の間には改行のみの 行が置かれます。本文の日本語は、JISコードで7ビットでエンコードされています。
ヘッダー
[CR LF]
本文(JISコード)
ヘッダーは、通常1行が1つのヘッダーです。長いヘッダーは、通常70バイト程度に 収まるように2行目の先頭文字が空白あるいはタブで継続する形式になっています。 本文は、送信者が改行コードを明示して指定しない限り、改行されずにそのまま の形式でメールサーバーから渡されます。 1行1000バイト以上の日本語を含む本文データを送信する場合、 メールクライアントによっては、行の途中で日本語が文字化けを起こす場合があります。

ヘッダーの日本語部分は、JISコードをさらにbase64で変換した形式です。 このヘッダーと本文の日本語部分のコード変換作業および次に述べるMIMEは、 メールクライアントの仕事でメール・サーバーは一切タッチしません。

本文だけでなく添付ファイルがある場合は、MIMEという仕様で本文とファイルデータを boundary文字列で区切ります。メールサーバーは、MIMEを意識せず、本文データと解釈します。 添付ファイルは、通常base64 エンコードされたテキストデータです。

ヘッダー
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="sep680007"
[CR LF]
--sep680007
[MIMEヘッダー]
本文
--sep680007
[MIMEヘッダー]
添付ファイル1
--sep680007
[MIMEヘッダー]
添付ファイル2
--sep680007--
この受信したRFC822ファイルを解釈してヘッダー、本文、添付ファイルに分離して 取り出すにはReadMailメソッドを使います。
■ 受信ファイル名(UIDLX)
RcvMailメソッドで受信したメールは、UIDLX(BASP21 Pro用語) というUIDL を ベースにしたファイル名がつけられて一通ごとに作成されます。 ファイル名のサンプルです。
c:\test\env1\mailbox\3a92700d00000001
c:\test\env1\mailbox\3a92700d00000002
c:\test\env1\mailbox\3a92700d00000003

UIDL は、POP3コマンドのUIDL でサーバーから返されるユニークなメールの識別子です。 UIDLX は、このUIDL文字をファイル名として対応させるため、英数字とピリオド以外の 文字を "X" をつけて16進文字に変換したIDです。

BASP21 Pro は、メール受信時にUIDLコマンドを必ず発行してメール番号に対応するUIDLを 読込みます。読込むディレクトリ内に同じUIDLX名を持つファイルがある場合は、 既読メールと判断し、そのメール内容をサーバーから読込みません。 ディレクトリ内にそのUIDLX名のファイルがない場合は、新着メールとみなし、サーバーから メールを読込み、ファイルをUIDLX名で作成します。

■ メールの削除
RcvMailメソッドで受信したメールファイルをディレクトリから削除するには VBScript組み込みオブジェクトのFileSystemObjectを使います。
Set fs = Server.CreateObject("Scripting.FileSystemObject")
fs.DeleteFile bobj.MailBox & "\new\" & "acf00000001234"

SortMailメソッドを使うと条件に合った メールファイルのみを削除することができます。

ar = bobj.SortMail(bobj.MailBox,"",0,"Date:=2001/02",1)
If bobj.Result > 0 Then
   cmd = "DELU " & Join(ar,",")
   outarray = bobj.RcvMail(user,pass,cmd)  ' メール・サーバーからも削除
End If
同時にメール・サーバーから削除するには DELUコマンドを使います。
■ UIDLとUIDLX
UIDLとは、メールサーバがメールにつけるユニークなIDです。 UIDLは、RcvMailメソッドのUIDLコマンドで受信することができます。 UIDLXは、BASP21 用語でメールサーバからのメール固有のUIDL を受信メールの 保存ファイル名に対応させるため、英数字(Xを除く)とピリオド以外の文字に Xをつけて16進文字に変換したIDです。

RcvMailメソッドでメールサーバから受信したメールファイル名は、UIDLXとなります。
RcvMailメソッドのDELUコマンドを使うと、UIDLX を指定してメールサーバから メールを削除できます。ローカルなフォルダに保存したメールファイルを 同時に削除するときに便利です。

ここでは、UIDLとUIDLXを相互に変換する方法を説明します。
以下の関数は、UIDLからUIDLX に変換します。

' UIDL-> UIDLX convert
Function UIDL2X(uidl)
  Dim ch,i,j,dlen,out,tbl
  dlen = Len(uidl)
  out = ""
  tbl = "0123456789ABCDEF"
  For i = 1 to dlen
    ch = Mid(uidl,i,1)
    If ((ch >= "0" And ch <= "9") Or _
           ch = "." Or _
           (ch >= "a" And ch <= "z") Or _
           (ch >= "A" And ch <= "Z" And ch <> "X") ) Then
      out = out & ch
    Else
      out = out & "X"
      j = Clng(Asc(ch))
      out = out & Mid(tbl,((j \ 16) And 15) + 1,1)
      out = out & Mid(tbl,(j And 15) + 1,1)
    End If
  Next
  UIDL2X = out
End Function
以下の関数は、UIDLXからUIDL に変換します。
' UIDLX --> UIDL convert
Function X2UIDL(uidlx)
  Dim ch,ch2,i,j,j2,dlen,out
  dlen = Len(uidlx)
  out = ""
  For i = 1 to dlen
    ch = Mid(uidlx,i,1)
    If ch <> "X" Then
      out = out & ch
    Else
      i = i + 1
      ch = Mid(uidlx,i,1)
      j = Clng(Asc(ch))
      If ch <= "9" Then
        j = j - 48
      Else
        If ch <= "F" Then
          j = j - 55
        Else
          j = j -87
        End if
      End If
      i = i + 1
      ch2 = Mid(uidlx,i,1)
      j2 = Clng(Asc(ch2))
      If ch2 <= "9" Then
        j2 = j2 - 48
      Else
        If ch2 <= "F" Then
          j2 = j2 - 55
        Else
          j2 = j2 - 87
        End If
      End If
      out = out & Chr(j * 16 + j2)
    End If
  Next
  X2UIDL = out
End Function


■ 受信したメールを読むには

BASP21 Pro では、ReadMailメソッドを使って RcvMailメソッドで保存した受信メールの ヘッダー、本文の読込み、添付ファイルを展開します。

RcvMailで受信、保存された受信メールは、RFC822形式のファイルです。 日本語を含んだメールの場合、ヘッダーや本文の日本語は、base64 やJISコードで エンコードされてます。 添付ファイルは、本文の後ろにMIME仕様でエンコードされているために、 そのままでは取り出すことはできません。

ここでは受信したメールの読み方やディレクトリ内に保存したメールのソート、 選択方法などを解説します。

ここでは次のトピックを説明します。

■ ヘッダーの読み方
メールヘッダーは、 ReadMailメソッドの第2パラメータで指定します。
mfile = bobj.MailBox & "\3ab9b19100000001"
ar = bobj.ReadMail(mfile,"from:subject:date:")
rc = bobj.Result 
If rc > 0 Then
  mailfrom = ar(0)  ' Formヘッダーの取出し
  subject = ar(1)   ' Subjectヘッダーの取出し
  dates = ar(2)     ' Dateヘッダーの取出し
End If
正常に終了した場合は、ReadMailメソッドの戻り値には、パラメータで指定したヘッダーが 順番に配列で返ります。 Received ヘッダーなど一部のヘッダーは2つ以上存在する場合があります。 第2パラメータを省略するか""を指定するとすべてのヘッダーを返します。
ar = bobj.ReadMail(mfile)
Dateヘッダーは、BASP21 Proが動作するマシンのローカル時間に合わせて変更されます。
Date: 2001/03/22 17:00:00
マシンのローカル時間は、[コントロールパネル]-[日付と時刻]-[タイムゾーン]で変更できます。 タイムゾーンを変更すると他の日付を扱うプログラムに影響しますので、タイムゾーンの変更はお勧めしません。 マシンのローカル時間を変更せずに Dateヘッダーの時間を調整するには timebiasパラメータを設定します。
----------------- basp21p.ini -------------------------------------------
[hawaii]
timebias=-19
bobj.Env = "hawaii"
ar = bobj.ReadMail(mfile)
■ 本文の読み方
本文は、ヘッダーの後に "Body: " で始まるデータです。
ar = bobj.ReadMail(mfile,"from:subject:date:")
rc = bobj.Result 
If rc > 0 Then
   For Each line in ar
     If InStr(line,"Body: ") = 1 Then
       body = Mid(line,7)   ' 本文の取出し
     End If
   Next
End If
本文を返さないようにするには "nobody:" を指定します。
ar = bobj.ReadMail(mfile,"from:subject:date:nobody:")
■ 添付ファイルを取出す
添付ファイルは、第3パラメータに保存するディレクトリを指定します。 第3パラメータを省略すると MailBoxプロパティ のディレクトリのattach サブディレクトリとみなされます。
ar = bobj.ReadMail(mfile,"from:subject:date:","c:\temp")
添付ファイル名は、ReadMailの戻り値配列の本文の後に "File: " で始まるデータです。
ar = bobj.ReadMail(mfile,"from:subject:date:")
rc = bobj.Result 
If rc > 0 Then
   For Each line in ar
     If InStr(line,"File: ") = 1 Then
       files = files & "," & Mid(line,7)    ' 添付ファイル名の取出し
     End If
   Next
End If
デフォルトでは添付ファイルの保存ディレクトリに同名のファイルが存在する場合には 上書きされます。上書きしたくない場合は、readmailoptパラメータでファイル名の 扱いを指定できます。
----------------- basp21p.ini -------------------------------------------
[iis5]
readmailopt=2
■ 添付ファイルを保存しないで読みたい
添付ファイルを保存したくない場合は、第2パラメータに"nofile:"を指定します。 この場合は、"File: " で始まるファイル名は返りますが保存はされません。
ar = bobj.ReadMail(mfile,"from:subject:date:nofile:")
またはreadmailoptパラメータを指定します。
----------------- basp21p.ini -------------------------------------------
[iis5]
readmailopt=1
■ ソートして表示したい
受信したメールを通常のメール・クライアントのように日付などでソートするには SortMailメソッドを使います。
以下は、新しい日付順にソートして表示データをTABLEタグで作成するVBScriptサンプルです。
----------------- sortmail01.asp -------------------------------------------
Set bobj = WScript.CreateObject("basp21pro","basp21pro_")
bobj.Env = "env1"
ar = bobj.SortMail(bobj.MailBox,"Date:",1)
rc = bobj.Result 
html = "<HTML><BODY><TABLE>"
If rc > 0 Then
   For Each line in ar
     mfile = bobj.MailBox & "\" & line
     mdata = readmailtag(mfile)
     html = html & vbCrLf & mdata
   Next
End If
html = html & vbCrLf & "</TABLE></BODY></HTML>"
Function readmailtag(fname)
  Dim ar,mfile,rc,mailfrom,subject,maildate
  ar = bobj.ReadMail(fname,"from:subject:date:nobody:nofile:")
  rc = bobj.Result 
  If rc > 0 Then
     mailfrom = bobj.RepTagChar(ar(0))
     subject = bobj.RepTagChar(ar(1))
     maildate = ar(2)
  End If
  readmailtag = "<TR><TD>" & mailfrom & "</TD><TD>" & subject & _
                 "</TD><TD>" & maildate & "</TD></TR>"
End Function
以下は、上記と同じ機能を持つJScriptサンプルです。
----------------- jsortmail01.asp -------------------------------------------
var bobj,rc,vbarray,ar,crlf;
crlf = unescape("%0D%0A");
set bobj = Server.CreateObject("basp21pro");
bobj.Env = "env1";
vbarray = bobj.SortMail(bobj.MailBox,"Date:",1);
rc = bobj.Result;
html = "<HTML><BODY><TABLE>";
if (rc > 0) {
   ar = vbarray.toArray();
   var i;
   for (i = 0; i < rc ; i++) {
     mfile = bobj.MailBox + "\\" + ar[i];
     mdata = readmailtag(mfile);
     html = html + crlf + mdata;
   }
}
html = html + crlf + "</TABLE></BODY></HTML>";
function readmailtag(fname)
{
  var vbarray,ar,rc,mailfrom,subject,maildate;
  vbarray = bobj.ReadMail(fname,"from:subject:date:nobody:nofile:");
  rc = bobj.Result;
  if (rc > 0) {
     ar = vbarray.toArray();
     mailfrom = bobj.RepTagChar(ar[0]);
     subject = bobj.RepTagChar(ar[1]);
     maildate = ar[2];
     return "<TR><TD>" + mailfrom + "</TD><TD>" + subject +
                 "</TD><TD>" + maildate + "</TD></TR>";
  }
  return "";
}
■ キーワードで選択して表示したい
受信したメールをキーワードで選択するにはSortMailメソッド を使います。
SortMailメソッドの第4パラメータにヘッダ名 + 条件 + 文字列で指定します。 文字列は、大文字小文字を無視して処理します。
以下は、Fromヘッダーに"freemail" を含むメールのみソートして、 表示データをTABLEタグで作成するVBScriptサンプルです。
----------------- sortmail02.asp -------------------------------------------
Set bobj = Server.CreateObject("basp21pro")
bobj.Env = "env1"
ar = bobj.SortMail(bobj.MailBox,"Date:",1,"from:=freemail")
rc = bobj.Result 
html = "<HTML><BODY><TABLE>"
If rc > 0 Then
   For Each line in ar
     mfile = bobj.MailBox & "\" & line
     mdata = readmailtag(mfile)
     html = html & vbCrLf & mdata
   Next
End If
html = html & vbCrLf & "</TABLE></BODY></HTML>"
Function readmailtag(fname)
  Dim ar,mfile,rc,mailfrom,subject,maildate
  ar = bobj.ReadMail(fname,"from:subject:date:nobody:nofile:")
  rc = bobj.Result 
  If rc > 0 Then
     mailfrom = bobj.RepTagChar(ar(0))
     subject = bobj.RepTagChar(ar(1))
     maildate = ar(2)
  End If
  readmailtag = "<TR><TD>" & mailfrom & "</TD><TD>" & subject & _
                 "</TD><TD>" & maildate & "</TD></TR>"
End Function
以下は、上記と同じ機能を持つJScriptサンプルです。
----------------- jsortmail02.asp -------------------------------------------
var bobj,rc,vbarray,ar,crlf;
crlf = unescape("%0D%0A");
set bobj = Server.CreateObject("basp21pro");
bobj.Env = "env1";
vbarray = bobj.SortMail(bobj.MailBox,"Date:",1,"from:=freemail");
rc = bobj.Result;
html = "<HTML><BODY><TABLE>";
if (rc > 0) {
   ar = vbarray.toArray();
   var i;
   for (i = 0; i < rc ; i++) {
     mfile = bobj.MailBox + "\\" + ar[i];
     mdata = readmailtag(mfile);
     html = html + crlf + mdata;
   }
}
html = html + crlf + "</TABLE></BODY></HTML>";
function readmailtag(fname)
{
  var vbarray,ar,rc,mailfrom,subject,maildate;
  vbarray = bobj.ReadMail(fname,"from:subject:date:nobody:nofile:");
  rc = bobj.Result;
  if (rc > 0) {
     ar = vbarray.toArray();
     mailfrom = bobj.RepTagChar(ar[0]);
     subject = bobj.RepTagChar(ar[1]);
     maildate = ar[2];
     return "<TR><TD>" + mailfrom + "</TD><TD>" + subject +
                 "</TD><TD>" + maildate + "</TD></TR>";
  }
  return "";
}
■ キーワードで選択してファイルを削除したい
受信したメールをキーワードで選択してファイルを削除するにはSortMailメソッド を使います。
SortMailメソッドの第4パラメータにヘッダ名 + 条件 + 文字列で指定します。 文字列は、大文字小文字を無視して処理します。 第5パラメータに 1 指定すると削除します。
以下は、Fromヘッダーに"freemail" を含むメールのみを削除するBScriptサンプルです。
----------------- sortmail03.asp -------------------------------------------
Set bobj = Server.CreateObject("basp21pro")
bobj.Env = "env1"
ar = bobj.SortMail(bobj.MailBox,"",0,"from:=freemail",1)
以下は、上記と同じ機能を持つJScriptサンプルです。
----------------- jsortmail03.asp -------------------------------------------
var bobj,rc,vbarray,ar,crlf;
crlf = unescape("%0D%0A");
set bobj = Server.CreateObject("basp21pro");
bobj.Env = "env1";
vbarray = bobj.SortMail(bobj.MailBox,"",0,"from:=freemail",1);
■ 件名や本文の内容で返答メールを送信したい
受信したメールの件名や本文の内容によって返答メールを送信するには:
まずSortMailメソッドでメールを選択して SendMailメソッドでメールを送信します。
SortMailメソッドの第4パラメータにヘッダ名 + 条件 + 文字列で指定します。 文字列は、大文字小文字を無視して処理します。
以下は、Subjectヘッダーに"basp21" を含むメールのみ選択して、 FromヘッダーまたはReply-Toヘッダーにメールを返信するVBScriptサンプルです。
----------------- reply01.asp -------------------------------------------
Dim bobj,ar,rc,ctr
Set bobj = Server.CreateObject("basp21pro")
bobj.Env = "env1"
ar = bobj.SortMail(bobj.MailBox,"",0,"subject:=basp21")
rc = bobj.Result 
If rc > 0 Then
   For Each line in ar
     mfile = bobj.MailBox & "\" & line
     mailto = getmailto(mfile)
     putmail mailto
     ctr = ctr + 1
   Next
End If
If ctr > 0 Then
  bobj.FlushMail
End If
Function getmailto(fname)
  Dim ar,rc,mailto
  ar = bobj.ReadMail(fname,"reply-to:from:")
  rc = bobj.Result 
  If rc > 0 Then
     mailto = Mid(ar(0),10)
     mailto = Trim(mailto)
     If Len(mailto) <= 0 Then
        mailto = Mid(ar(1),6)
        mailto = Trim(mailto)
     End If
  End If
  getmailto = mailto
End Function
Sub putmail(mailto)
  Dim fso,f
  subject = "資料送付"
  Set fso = Server.CreateObject("Scripting.FileSystemObject")
  Set f = fso.OpenTextFile(bobj.Home & "\body.txt", 1)
  body = f.ReadAll
  files = bobj.Home & "\basp21.doc"
  bobj.SendMail mailto,subject,body,files
End Sub
以下は、上記と同じ機能を持つJScriptサンプルです。
----------------- jreply01.asp -------------------------------------------
var bobj,vbarray,ar,rc,ctr;
bobj = Server.CreateObject("basp21pro");
bobj.Env = "env1";
vbarray = bobj.SortMail(bobj.MailBox,"",0,"subject:=basp21");
rc = bobj.Result ;
ctr = 0;
if (rc > 0) {
   ar = vbarray.toArray();
   var i,mfile,mailto;
   for (i = 0; i < rc; i++) {
     mfile = bobj.MailBox + "\\" + ar[i];
     mailto = getmailto(mfile);
     putmail(mailto);
     ctr++;
   }
}
if (ctr > 0) {
  bobj.FlushMail();
}
function getmailto(fname)
{
  var vbarray,ar,rc,mailto;
  vbarray = bobj.ReadMail(fname,"reply-to:from:")
  rc = bobj.Result;
  if (rc > 0 ) {
     ar = vbarray.toArray();
     mailto = ar[0].substr(9);
     if (mailto.length <= 1) {
        mailto = ar[1].substr(5);
     }
     mailto = mailto.replace(/(^\s*)|(\s*$)/g, "");
  }
  return mailto;
}
function putmail(mailto)
{
  var fso, f,subject,body,files;
  subject = "資料送付";
  fso = Server.CreateObject("Scripting.FileSystemObject");
  f = fso.OpenTextFile(bobj.Home + "\\body.txt", 1);
  body = f.ReadAll();
  files = bobj.Home + "\\basp21.doc";
  bobj.SendMail(mailto,subject,body,files);
}
■ メールの受信(ASP.NET C#)
ここでは ASP.NET環境でメール受信のサンプルプログラムをC#で紹介します。
RcvMail のLISTコマンドでメールの一覧を表示してから、 メール番号をクリックするとメール内容が表示されるサンプルです。
----------------- rcvm01.aspx -------------------------------------------
<%@ PAGE validateRequest="false"%> 
<%@ Assembly name="BASP21PROLib" %>
<%@ Import namespace="BASP21PROLib" %>
<html><head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<script language="C#" runat="server">
void Page_Load(object sender, EventArgs e)
{
  if (!IsPostBack) {
    name.Value = "";
    pass.Value = "";
  }
  if (Request.QueryString["f"] != null) {  // メール番号選択?
      int n = int.Parse(Request.QueryString["f"]);
      if (n > 0) {
          showmail(n); // メール内容表示
      }
  }
}
void submit_click(object sender, EventArgs e) // メール一覧表示
{
  basp21p bobj;
  object ar;
  string outstr;
  int rc,mail_count;
  bobj = new basp21p();
  bobj.Env = "iis6";
  ar = bobj.RcvMail(name.Value,pass.Value,"list","");
  mail_count = bobj.Result;
  outstr = "";
  if (mail_count > 0) {
    Session["name"] = name.Value; // ユーザ名
    Session["pass"] = pass.Value; // パスワード
    int i = 0;
    foreach (string list in (Array)ar) { // メール一覧をHTMLデータに展開
        string line = Server.HtmlEncode(list.Substring(9));
        i++;
        string num = i.ToString();
        outstr = outstr + "<TR><TD><A HREF=rcvm02c.aspx?f=" + num + ">" +
                           num + "</A></TD>";
        line = line.Replace("\tFrom: ","\t");
        line = line.Replace("\tDate: ","\t");
        line = line.Replace("\t","</TD><TD>");
        outstr = outstr + "<TD>" + line + "</TD></TR>\r\n";
    }
    outstr = "<TABLE border=2>" + outstr + "</TABLE>";
  }
  Message.InnerHtml = outstr;
}
void showmail(int n)  // メール内容表示
{
  if (Session["name"] == null) {
     Message.InnerHtml = "session timeout!!!";
     return;
  }
  basp21p bobj;
  object ar;
  string outstr;
  int rc,mail_count;
  bobj = new basp21p();
  bobj.Env = "iis6";
  string command = "save " + n.ToString();
  string namestr = Session["name"].ToString();
  string passstr = Session["pass"].ToString();
  ar = bobj.RcvMail(namestr,passstr,command,"");
  mail_count = bobj.Result;
  outstr = "";
  if (mail_count > 0) {
    Array arx = (Array) ar;
    ar = bobj.ReadMail((string)arx.GetValue(0),"subject:from:date:","");
    foreach (string list in (Array)ar) {
        outstr = outstr + list + "\r\n";
    }
  }
  Message.InnerHtml = "<PRE>" + Server.HtmlEncode(outstr) + "</PRE>";
}
</script>
</head>
<body>
  <form runat="server">
   name:<input type=text id="name" runat="server"><BR>
   pass:<input type=password id="pass" runat="server"><BR>
   <input type=submit value="Submit" 
             OnServerClick="submit_click" runat="server">
  </form>
  <B><span id="Message" runat=server></span></B>
</body>
</html>

■ ファイルアップロード

BASP21 Pro は、ファイルアップロード機能(RFC1867)をサーバサイド(Form*メソッド)および クライアントサイド(UpLoadメソッド)でも実装しています。 ここではRFC1867の基礎知識からASPアプリケーションでのファイルアップロード方法の 実際を解説します。

ここでは次のトピックを説明します。

■ RFC1867(Form-based File Upload in HTML)
RFC1867(November 1995)は、HTMLのフォームを使ってサーバーにファイルデータをPOST する仕様または 実装です。 ファイルやフォーム内のデータは、boundary 文字列 で区切られて、まとめて HTTPプロトコルで送信されます。 ファイルのバイナリデータは、そのままエンコードされずに直接送信されます。
POSTデータは、次のような形式になります。
----separator20010301
Content-Disposition: form-data; name="yourname"

BASP21 Pro
----separator20010301
Content-Disposition: form-data; name="file1"; filename="C:\TEMP\upload.jpg"
Content-Type: application/octet-stream

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

----separator20010301--
POSTデータは、最初が区切り文字(----separator20010301 + CRLF)、 次にテキストデータやファイルのフィールド名(name="xxxx")、 フィールド種別(Content-Type)を示すヘッダー、実際のデータ、区切り文字、次のフィールド、 というようにフォームのフィールド別に送信されます。 最後の区切り文字には "--" が追加されます。
通常、サーバ側ではクライアントから受取ったPOSTデータを、区切り文字により 各フィールドに分解して、ファイルやデータベースなどに保存します。

サーバサイドにPOSTされたデータを扱うBASP21 Proメソッドを次に示します。
メソッド説明
Form INPUT TYPE="TEXT"タグなどで送信されたテキストデータ取得。
FormBinary テキストデータやファイルデータをバイナリデータとして取得。
FormFileName INPUT TYPE="FILE"タグで送信されたファイル名を取得。
FormFileSize INPUT TYPE="FILE"タグで送信されたファイルサイズを取得。
FormSaveAs INPUT TYPE="FILE"タグで送信されたファイルをサーバーに保存。

■ ブラウザのRFC1867機能
ブラウザは、RFC1867の実装としてフォームのINPUTタグ(TYPE="FILE")で アップロードするファイルを指定するテキストボックスを表示します。 また、テキストボックスの横の[参照]ボタンを押すとダイアログからファイルを 選択できます。
次のようなHTMLテキストでファイルをアップロードするフォームを表示することができます。
----------------- fileup01.html -------------------------------------------
<HTML><BODY>
<FORM ACTION="fileup.asp"  ENCTYPE="multipart/form-data" METHOD="POST">
氏名: <INPUT TYPE=TEXT NAME="yourname"><BR>
ファイル1: <INPUT TYPE=FILE NAME="file1"><BR>
ファイル2: <INPUT TYPE=FILE NAME="file2"><BR>
<INPUT TYPE=SUBMIT NAME=UPLOAD>
</FORM></BODY></HTML>
ACTIONパラメータには、サーバサイドでデータを受け取るCGIやASPファイル名を指定します。 この例ではASPファイルのパス名指定がありませんので上記のHTMLファイルは ASPファイルと同じ仮想ディレクトリに置かれます。

ENCTYPEには"multipart/form-data"を METHOD は、POST を指定します。 ファイルの指定は、INPUTタグのTYPE=FILE を使います。 現状のブラウザのRFC1867実装ではTYPE=FILE を指定した場合、セキュリティに配慮し、 テキストボックス内にファイル名の初期値をVALUE= で設定することはできない仕様と なっています。この仕様は、IEでもNetscapeでも同じです。

実際にブラウザからどんなデータが送信されているか確認するには 次のような asp ファイルを実行してみましょう。

----------------- fileup02.asp -------------------------------------------
<%
a=Request.TotalBytes
b=Request.BinaryRead(a)
Response.Expires = 0
Response.Buffer = TRUE
Response.Clear
Response.ContentType= "application/x-binary"
Response.AddHeader "Content-Disposition","Attachment; filename=""your.dat"""
Response.BinaryWrite b
Response.End
%>
上記のスクリプトは、クライアントから受信したアップロード内容をそのままブラウザに 送り返しています。送り返されたデータは、ブラウザが表示する保存ダイアログを使って 保存してエディタなどで確認することができます。 RFC1867形式で各フィールドが区切られているはずです。

IEアップロード(TYPE=FILE)をスピードアップするには、 Windowsレジストリを編集して、SocketSendBufferLength にWinsockの送信バッファサイズを 設定する方法があります。 詳細は、マイクロソフトのサイトHTTP File Upload Operation Takes a Long Time to Completeを参照してください。

ブラウザのフォーム(TYPE=FILE)を使わずに、UpLoadメソッドを使って ブラウザやVBAなどからアップロードすることも可能です。

■ BASP21 Proを使うサーバサイド・スクリプト
POSTデータは、ASP組込みオブジェクトのRequest.BinaryReadメソッドでアクセスできます。 RFC1867関連のBASP21 Proのメソッドの第一パラメータには、 Request.BinaryReadメソッドで取得したPOSTデータ変数を指定します。 第2パラメータにはフォームで指定したフィールド名(name="xxxx")を指定します。

通常は、POSTデータ内のファイル名やテキストデータなどの日本語データは SJISコードとして処理します。 FormメソッドFormFileNameメソッドには第3パラメータとして文字コードを指定できます。

----------------- fileup03.asp -------------------------------------------
<%
a=Request.TotalBytes       ' POSTデータの合計サイズ
b=Request.BinaryRead(a)    ' POSTデータを取得
set bobj=Server.CreateObject("basp21pro")
name=bobj.Form(b,"yourname")
fname=bobj.FormFileName(b,"file1")
fname=Mid(fname,InstrRev(fname,"\")+1)
fsize=bobj.FormSaveAs(b,"file1","c:\temp\" & fname)
If fsize < 1 Then ' エラー
  msg = bobj.LastMsg
Else
  msg = fsize
End If
%>
<HTML><HEAD><TITLE>File Upload Test</TITLE>
<BODY>
<H1>Testing</H1>
<BR>
<%= name %>さん、アップロードされました<BR>
file size= <%= msg %><BR>
</BODY></HTML>
テキストデータやチェックボックスフィールドの値を取得するには Formメソッドを使います。 SELECTタグで複数選択(MULTIPLE)データをFormメソッドで取得した場合、 各データはタブで区切られます。

FormSaveAsメソッドは、受信したファイルデータをサーバー側のファイルに書き込みます。 ASP環境でIIS匿名認証の場合は、IUSR_マシン名アカウントのセキュリティコンテキストで BASP21 Proのメソッドが動作します。書き込むドライブがNTFSファイルシステムの場合、 アクセス権を適切に設定する必要があります。

スクリプトの書き方としてFormSaveAs メソッドの戻り値をチェックしてクライアントに 応答を返すようにしましょう。

■ アップロードできる最大ファイルサイズは
BASP21 Pro を使ったサーバサイドスクリプトは、ASP組み込みオブジェクトの Request.BinaryRead メソッドを使用します。 アップロードできる最大ファイルサイズは、1GB程度となります。

一度に大きいサイズのファイル(50MB以上)をアップロードする場合は、 Request.BinaryRead メソッドとFormSaveAsメソッドのペアを繰返し呼ぶ必要があります。

大きいファイルをアップロードする場合、スクリプトタイムアウト値を長めに指定します。 以下に Request.BinaryReadメソッドを繰返し呼ぶサンプルを示します。

----------------- hugeupload.asp -------------------------------------------
<%
starttime = Now()
Server.ScriptTimeout=72000
totalbytes=Request.Totalbytes
bufferlen = 1024 * 1024  ' バッファ長 1MB
rlen = bufferlen
b=Request.BinaryRead(rlen)
set bobj = Server.Createobject("basp21pro")
bobj.Env = "env1"
fname = bobj.FormFileName(b,"file001")  ' 1回目のBinaryRead後に呼出し
para = bobj.Form(b,"Para")              ' 1回目のBinaryRead後に呼出し
fpath = "c:\temp" & Mid(fname,InstrRev(fname,"\"))
rc = bobj.FormSaveAs(b,"file001",fpath,4)  '最初の呼出しでは 4 指定
filelen = rc
readlen = rlen
Do While readlen < totalbytes And rc >= 0
  If Not Response.IsClientConnected() Then  ' キャンセル?
     rc = bobj.FormSaveAs(b,"file001",fpath,6)  ' ファイル削除
     Exit Do
  End If
  rlen = bufferlen
  On Error Resume Next
  b=Request.BinaryRead(rlen)
  If Err.number <> 0 then
     rc = bobj.FormSaveAs(b,"file001",fpath,6)  ' ファイル削除
     Exit Do
  End If
  On Error Goto 0
  readlen = readlen + rlen
  rc = bobj.FormSaveAs(b,"file001",fpath,5)  '2回目以降の呼出しでは 5 指定
  filelen = filelen + rc
Loop
%>
<HTML>
<BODY>
処理秒数: <%= DateDiff("s",starttime,now()) %><BR>
totalbytes: <%= totalbytes %><BR>
readlen: <%= readlen %><BR>
fname: <%= fname %><BR>
Para: <%= Para %><BR>
fpath: <%= fpath %><BR>
filelen: <%= filelen %><BR>
rc: <%= rc %><BR>
</BODY>
</HTML>
■ 大きいファイルを分割アップロードする
UpLoadメソッドの分割オプション("-G size") を使うと、サーバーの負担なしに 大きいサイズのファイルをアップロードできます。 分割オプションは、ファイルを指定サイズで分割して、サーバーに送信します。 サーバーサイドでは、FormSaveAsメソッドの追加モードでファイルを保存します。 分割オプションを使う場合は、2GB以上のファイルをアップロードできます。

size にはMB単位の分割サイズを指定します。 URLで指定したサーバーサイド・スクリプトが分割サイズに応じて、 複数回呼出され実行されます。 最適な分割サイズは、IIS環境によって異なります。 以下の例は、5MB単位でファイルをアップロードするクライアントサイドのVBScriptサンプルです。

bobj.ShowDIalog = 1
fname = bobj.Home & "\" & "bigdata.dat"
url = "http://www.basp21.com/test/bigfileup.asp"
rc = bobj.UpLoad(url,fname,"-G 5")
分割オプションを使った場合は、サーバサイドのFileSaveAsメソッドの 第4パラメータの追加モードを指定してファイルを保存する必要があります。 以下の例は、FormSaveAsメソッドを使うVBScriptサンプルです。
----------------- bigfileup.asp -------------------------------------------
<%
Response.Buffer = True
Response.Clear
Server.ScriptTimeout = 3600
a=Request.TotalBytes
b=Request.BinaryRead(a)
Set bobj=Server.CreateObject("basp21pro")
name=bobj.FormFileName(b,"xfile001")
name=Mid(name,InstrRev(name,"\")+1)
fsize=bobj.FormSaveAs(b,"xfile001","c:\temp\" & name,2)  ' 追加モード
If fsize <= 0 Then   ' エラーの場合は、UpLoadメソッドを中断させるために
                        '  200 番台以外のResponse.Status を返してください
  Response.Write "<HTML><BODY>506" & bobj.LastMsg & "</BODY></HTML>"
  Response.Status = "506 " & bobj.LastMsg
  Response.End
End If
%>
<HTML><HEAD><TITLE>File Upload with -G option</TITLE>
<BODY>
fsize= <%= fsize %><BR>
fname= <%= fname %><BR>
</BODY></HTML>
■ BFup Proでフォルダアップロード
BFup Pro を使うとhttpモードでフォルダ(サブフォルダも含む)を一気にアップロード可能です。 サーバーサイドでは、FormSaveAsメソッドの追加モードでファイルを保存します。

BFup ProのSplitSizeプロパティ にはKB単位の分割サイズを指定します。 BFup のModifiedプロパティには"#ftpmode 2" を指定します。 URLで指定したサーバーサイド・スクリプトが分割サイズに応じて、 複数回呼出され実行されます。 以下の例は、512KB単位でファイルをアップロードするサンプルです。

(fileup3.html)
<HTML><BODY>
<OBJECT ID="BFUP"
 CLASSID="CLSID:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">
    <PARAM NAME="URL" VALUE="fileup3.asp">
    <PARAM NAME="Exec" VALUE="UpLoad">
    <PARAM NAME="FilePath" VALUE="">
    <PARAM NAME="SplitSize" VALUE="512">
    <PARAM NAME="modified" VALUE="#ftpmode 2">
    <PARAM NAME="TransParent" VALUE="1">
</OBJECT>
</BODY></HTML>

(fileup3.asp)
<%@ Language="VBScript"  %>
<%
option explicit
dim bobj,objFs,upload_path,org_file_path,save_file_path
dim save_dir,a,b,mode,splitinfo,fsize
Set bobj = Server.CreateObject("basp21pro")
Set objFs = Server.CreateObject("Scripting.FileSystemObject")
a=Request.TotalBytes
b=Request.BinaryRead(a)
upload_path="c:\temp\upload"  ' 保存フォルダ名
org_file_path=bobj.FormFileName(b,"xfile001") ' クライアント側ファイル名
save_file_path = upload_path & "\" & Mid(org_file_path,4)
save_dir = objFs.GetParentFolderName(save_file_path)
CreateFolders save_dir  ' サブフォルダがなければ作成
splitinfo=bobj.Form(b,"split")
If Len(splitinfo) = 0 or Mid(splitinfo,1,2) = "1/" Then  ' 最初のデータ
  mode = 0
Else
  mode = 2  ' 追加モード
End If
fsize=bobj.FormSaveAs(b,"xfile001",save_file_path,mode) ' 保存
If fsize <= 0 Then
  Response.Write "<HTML><BODY>506" & bobj.LastMsg & "</BODY></HTML>"
  Response.Status = "506 " & bobj.LastMsg
  Response.End
End If
Sub CreateFolders(DirPath) ' フォルダ作成(階層化対応)
  Dim ParentFolderPath
  If Len(DirPath) > 3 Then
    If Not objFs.FolderExists(DirPath) Then
      ParentFolderPath = objFs.GetParentFolderName(DirPath)
      If Not objFs.FolderExists(ParentFolderPath) Then
        CreateFolders ParentFolderPath
      End If
      objFs.CreateFolder DirPath
    End If
  End If
End Sub
%>
<html><body>
<%= fsize %>
</body></html>

■ アップロード処理が遅い
IIS5 では既定値がプロセスの[分離レベル] が[中]で、これはASPスクリプトがIISの 外部プロセスで実行されるという意味です。 この[分離レベル] を[低]にするとASP が IIS の主要なプロセスである Inetinfo.exe の中で実行されますのでご確認ください。

ASPスクリプトの外部プロセスの名前は、Windows 2000 では DllHost.exe です。

IIS4では[IISプロセス内で実行]が既定値です。

■ FormSaveAsメソッドのエラー
FormSaveAsメソッドのよくあるエラーを エラー・ログレコードの例から説明します。
FormSaveAs ERROR:-6 [IUSR_xxxxx]createfile error c:\xxxx\xxxx 3:指定されたパスが見つかりません。  
【原因】
FormSaveAsの第3パラメータのディレクトリ名が間違っている
【対処】
FormSaveAsの第3パラメータに正しいディレクトリ名を指定する
FormSaveAs ERROR:-6 [IUSR_xxxxx]createfile error c:\xxxx\xxxx 5:アクセスが拒否されました。  
【原因】
FormSaveAsの第3パラメータのディレクトリにIUSR_xxxxx アカウントがアクセス権限がない
【対処】
FormSaveAsの第3パラメータのディレクトリのセキュリティダイアログでIUSR_xxxxx アカウント、
または Everyoneグループに対して書込み権を与える
FormSaveAs ERROR:-19 [IUSR_xxxxx]invalid arg xxxxx
【原因】
TYPE=FILE のNAMEタグの名前(NAME=)とFormSaveAsの第2パラメータで指定した名前が一致していない
【対処】
FormSaveAsメソッドの第2パラメータに該当NAMEタグの名前を正しく指定する
エラー・ログレコードは、最初のマイナスの数値がBASP21 Proのエラー番号、 意味(またはエラーを返したWin32 API名)、 プラスのシステムエラー番号(Win32 GetLastError関数の戻り値)と対応するメッセージです。
■ UpLoadメソッドでSSL暗号化通信機能を使うには
UpLoadメソッドでSSL暗号化通信機能を使うには URLパラメータに "http://"の代わりに "https://"を指定します。
rc = bobj.UpLoad("https://www.basp21.com/secure/fileup.asp","c:\secret","")

■ UpLoadメソッドを使うファイルアップロード

ここではブラウザのHTMLフォームを使わずにBASP21 ProのUpLoadメソッドを 使うアップロード方法を説明します。

ブラウザのHTMLフォームによるアップロード機能ではなくUpLoadメソッドを使う理由は:

■ クライアントからUpLoadメソッドを使う
クライアントからUpLoadメソッドを使ってアップロードするには、クライアント側にBASP21 Proを 事前にインストールしておく必要があります。または、 IEによる自動インストール機能により、 ページ実行時にBASP21 Proをクライアントにインストールすることもできます。 以下に、IEで JScript を使ってページ表示時に自動的にアップロードする スクリプト例を示します。
----------------- jupload04.html -------------------------------------------
<HTML><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<TITLE>BASP21 UpLoad</TITLE>
<BODY onLoad="upload()">
<OBJECT ID="bobj" CLASSID="CLSID:EC0C18A0-4D5E-11D4-896C-00000E4E0AD6"
  CODEBASE="BASP21P.CAB#version=1,0,3,1">
  <PARAM NAME="Env" VALUE="ie3.02">
</OBJECT>
<SCRIPT language="JavaScript">
function upload() {
  var filename = bobj.home + "\\log.lzh";
  status = filename;
  bobj.ShowDialog = 1;
  var rc = bobj.UpLoad("http://your-server/test/fileup1.asp",filename);
  status = "Done " + rc;
}
</SCRIPT>
<SCRIPT FOR="bobj" EVENT="OnLog(log)" LANGUAGE="JavaScript">
  status = log;
</SCRIPT>
<SCRIPT FOR="bobj" EVENT="OnProgress(msg,current,total)" LANGUAGE="JavaScript">
  status = msg;
</SCRIPT>
</BODY></HTML>
ポイントは:
■ UpLoadメソッドを処理するサーバサイド・スクリプト
ここではクライアントサイドでBASP21 ProのUpLoadメソッドを 使う場合のサーバーサイド・スクリプトの作成方法を説明します。 フィールドのタグ名(アップロードフォームのNAMEに相当)は、"xfile001" から "xfile999" までの 連番になります。
----------------- fileup05.asp -------------------------------------------
<%
Response.Buffer = True
Response.Clear
a=Request.TotalBytes       ' POSTデータの合計サイズ
b=Request.BinaryRead(a)    ' POSTデータを取得
set bobj=Server.CreateObject("basp21pro")
fname=bobj.FormFileName(b,"xfile001")
fname=Mid(fname,InstrRev(fname,"\")+1)
fsize=bobj.FormSaveAs(b,"xfile001","c:\temp\" & fname)
If fsize < 1 Then ' エラーの場合は、UpLoadメソッドを中断させるために
                        '  200 番台以外のResponse.Status を返してください
  Response.Write "<HTML><BODY>506" & bobj.LastMsg & "</BODY></HTML>"
  Response.Status = "506 " & bobj.LastMsg
  Response.End
Else
  msg = fsize
End If
%>
<HTML><HEAD><TITLE>File Upload Test</TITLE>
<BODY>
file size= <%= msg %><BR>
</BODY></HTML>
Uploadメソッドを使う場合には、FormSaveAsメソッド で第2パラメータに "*" を指定するとすべてのファイルをディレクトリに保存できます。
----------------- fileup05all.asp -------------------------------------------
<%
a=Request.TotalBytes
b=Request.BinaryRead(a)
set bobj=Server.CreateObject("basp21pro")
bobj.Env = "env1:" & Request.ServerVariables("REMOTE_ADDR")
dir = bobj.Home & "\fileup2"
rc=bobj.FormSaveAs(b,"*",dir)
msg=bobj.LastMsg
Set bobj = Nothing
%>
<HTML><HEAD><TITLE>File Upload All</TITLE>
<BODY>
<H1>Testing</H1>
<BR>
rc= <%= rc %><BR>
msg = <%= msg %>
</BODY></HTML>
JScript のサンプルを次に示します。JScript では "\" 文字は、"\\" のように2つ指定します。
----------------- jfileup05all.asp -------------------------------------------
<%@ LANGUAGE="JavaScript" %>
<%
var a = Request.TotalBytes;
var b = Request.BinaryRead(a);
var bobj = Server.CreateObject("basp21pro");
bobj.Env = "env1:JScript " + Request.ServerVariables("REMOTE_ADDR");
var dir = bobj.Home + "\\fileup2";
var rc = bobj.FormSaveAs(b,"*",dir);
var msg = bobj.LastMsg;
%>
<HTML><HEAD><TITLE>File Upload Test</TITLE>
<BODY>
<H1>Testing</H1>
<BR>
rc= <%= rc %><BR>
msg = <%= msg %>
</BODY></HTML>

■ FTPサーバーにアップロード
クライアントからFTPサーバーにファイルアップロードするには UpLoadメソッドを使います。 アップロードURLを"ftp://"で開始するとFTPモードでファイルのアップロードができます。
  var files = bobj.home + "\\*.html";
  var rc = bobj.UpLoad("ftp://your-ftp-server/dir1",files);
以下に、IEで JScript を使ってページ表示時に自動的にFTPサーバーにファイルを アップロードするスクリプト例を示します。
----------------- fileup06.html -------------------------------------------
<HTML><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<TITLE>BASP21 UpLoad</TITLE>
<BODY onLoad="upload()">
<OBJECT ID="bobj" CLASSID="CLSID:EC0C18A0-4D5E-11D4-896C-00000E4E0AD6"
  CODEBASE="BASP21P.CAB#version=1,0,3,1">
  <PARAM NAME="Env" VALUE="ie3.02">
</OBJECT>
<SCRIPT language="JavaScript">
function upload() {
  var filename = bobj.home + "\\*.html";
  status = filename;
  bobj.ShowDialog = 1;
  var rc = bobj.UpLoad("ftp://user1:pass1@your-ftp-server/html",filename);
  status = "Done " + rc;
}
</SCRIPT>
</BODY></HTML>
FTPアカウント名とパスワードは、"ftp://xxxx:yyyy@server" のように URLのサーバ名の前に "@" で区切って指定します。 あるいは BASP21P.INIファイルのftpuserpassパラメータ でも指定可能です。
----------------- basp21p.ini -------------------------------------------
[ie3.02]
allow=upload,showdialog
ftpuserpass=user1:pass1

■ PHPサーバーサイド・スクリプト
ここでは、クライアントからUpLoadメソッドでアップロードするサーバー側での PHPスクリプトの作成方法を説明します。 PHP(Personal Home Page tools)は、Apache Webサーバーに組込んで使われる HTML埋め込み型のサーバーサイドのスクリプト言語です。ApacheではPerl と並んで 使われることが多い人気のある言語です。

クライアントのUpLoadメソッドで指定したアップロードURLの スクリプトの拡張子が"php" または"php3"の場合は、サーバサイドのスクリプトをPHP とみなし、ファイルのフィールド名を"xfiles[]"(注:小文字)として送信します。 PHPでは変数名後の"[]" は、配列として解釈します。

  var rc = bobj.UpLoad("http://your-server/test/fileup2.php",bobj.home);

PHPのRFC1867実装は、アップロードに成功するとフィールドのタグ名がそのまま変数名となり PHPスクリプト内からアクセスできる仕様になっています。
PHP変数名説明
$xfiles[n] アップロードされて作成された一時的なファイル名
$xfiles_name[n] オリジナルのファイル名
$xfiles_size[n] ファイルのサイズ
$xfiles_type[n] ファイルのMIMEタイプ。application/octet-stream固定です

注意:PHPは、関数名(echo/Echoなど)の大文字小文字は区別しませんが、 変数名の大文字小文字は区別します。$XFILES[0]や$xfiles_NAME[$i]などでは アクセスに失敗します。

PHPではスクリプト実行時にアップロードする個々のすべてのファイルを一時的に PHPが内部的に作成する仕様になっています。 このファイルは、スクリプト終了時にPHPによって自動的に削除されますので、 保存するためには別のファイルにコピーする必要があります。

PHPアップロードでは"[]"を使うフィールド名は、配列(添字は0から)として扱うことができます。 変数$xfiles[0]がアップロードされた最初の一時ファイル名、 変数$xfiles[1]が2番目の一時ファイル名です。 次に UpLoadメソッドに対応するサーバー・サイドのPHPスクリプトサンプルを示します。

----------------- fileup07.php -------------------------------------------
<HTML><HEAD> <TITLE>UpLoad using PHP3</TITLE></HEAD>
<BODY>
<?php
  if (!isset($HTTP_POST_VARS)) {
    echo "no post data";
  } else {
    $path = '/tmp/upload/';
    $max = 999;
    echo "<table border=1>";
    echo "<tr><td>#</td><td>xfile</td><td>size</td></tr>";
    for ($i = 0;$i < $max;$i++) {
      if ($xfiles[$i] == '')
        break;
      $j = $i+1;
      echo "<tr><td>$j</td><td>$xfiles[$i]</td>";
      echo "<td>$xfiles_size[$i]</td></tr>";
      if (!copy($xfiles[$i],$path.$xfiles_name[$i]))
        echo "failed to copy $xfiles[$i]<br>\n";
    }
    echo "</table>";
  }
?>
</BODY>
</HTML>

■ ファイルダウンロード(ASP)

ファイルダウンロードは、クライアントにサーバ側のファイルを格納する処理です。
BASP21 Proを使ってダウンロードするには:
サーバサイドからResponse.BinaryWriteでファイルをバイナリでクライアントに 出力する方法と、クライアントサイドでDownLoadメソッドを使う方法があります。 DownLoadメソッドを使う場合は、サーバーサイドはASP環境でなくてもかまいません。
2つの方法を比較すると:
方式長所/短所
サーバサイドからResponse.BinaryWriteメソッドで出力 クライアントサイドのスクリプト不要。 IE、Netscape共にOK。 ブラウザ実装に依存、ブラウザのバージョンなどにより動作の違いが発生。 サーバーサイドはASPのみ。
クライアントでDownLoadメソッド 進捗状況表示可能。 日本語コード変換可能。 保存ダイアログを表示せずに自動ダウンロード可能。 HTTPだけでなくFTPプロトコルもサポート。 クライアントは、ブラウザ以外のクライアント(例えばExcel VBA) でもOK。 サーバーサイドは、ASP以外(Apache、FTPサーバーなど)もOK。 クライアントにBASP21 Proをインストールする必要あり。 コマンドライン(BHELPER.EXE)。ブラウザはIEのみで動作。 リジューム機能。
■ サーバサイドでResponse.BinaryWriteメソッドを使う
サーバーサイドのASPスクリプトでダウンロードするには、 BASP21 ProのBinaryReadメソッドでファイル内容を バイナリで読込み、ASP組込みオブジェクトのResponse.BinaryWriteメソッドで クライアントに出力します。
ダウンロードを実行するASPスクリプトにサンプルを示します。
----------------- download08.asp -------------------------------------------
<%
set bobj = SErver.CreateObject("basp21pro")
bobj.Env ="env1:" & Request.ServerVariables("REMOTE_ADDR")
fname = "data1.xls"
fpath = bobj.Home & "\" & fname
data = bobj.BinaryRead(fpath)
If Not bobj.IsError Then
  Response.Expires = 0
  Response.Buffer = TRUE
  Response.Clear
  Response.ContentType= "application/x-binary"
  para = "Attachment; filename=" & """" & fname & """"
  Response.AddHeader "Content-Disposition",para
  Response.BinaryWrite data
  Response.End
Else
  msg = bobj.LastMsg
  Response.Write "<HTML><BODY>" & vbCrLf
  Response.Write "<B>DownLoad Error</B><BR>" & msg & vbCrLf
  Response.Write "</BODY></HTML>" & vbCrLf
End If
%>
BinaryReadメソッドが次のようなエラー (LastMsgプロパティ)を返す場合は、 IUSR_xxxxx アカウントが該当ファイルに対してアクセス権がありません。 該当ファイルかまたはディレクトリを右クリックして、 セキュリティダイアログでIUSR_xxxxx アカウントを追加して読込み権を与える必要があります。
ERROR:-6 [IUSR_xxxxx]createfile error c:\test\xxxx.xxx 5:アクセスが拒否されました。  

200MBを越す大きいファイルの場合は、以下のように、BinaryReadメソッドと Response.BinaryWriteメソッドを繰返し呼び出します。
Response.BinaryWriteメソッドを連続して発行すると、サーバーに負荷がかかり、
サーバが不安定になりますので、Sleepメソッドで発行間隔を空ける必要があります。
<%
Server.ScriptTimeout = 60*30   ' タイムアウト30分
set bobj = Server.Createobject("basp21pro")
bobj.env="env1"
fname="1999mb.zip"  ' ファイルサイズは2GB -1 まで可能
filename="c:\temp\" & fname
offset = 0
rlen = 1024*1024*10  ' 10MBずつ読込み
flen = bobj.FileCheck(filename)
dlen = 0
readlen = 0
Response.Buffer = False   ' バッファリングしない
Response.ContentType = "application/octet-stream;name=" & fname
Response.AddHeader "Accept-Ranges", "bytes"
Response.AddHeader "Content-Disposition","attachment;filename=" & fname
Response.AddHeader "Content-Length",flen   ' IIS 7.5 ではContent-Lengthはコメントにすること
Do While dlen < flen
  dat = bobj.binaryread(filename,offset,rlen)
  rc = bobj.result
  If rc < 0 Then Exit Do    ' 読込みエラー
  Response.BinaryWrite dat
  If Not Response.IsClientConnected() Then Exit Do  ' 切断の場合、処理中断
  bobj.Sleep 4   ' 4秒待つ  サーバの負荷状態で待ち秒数を増減
  readlen = readlen + rc
  offset = offset + rlen
  If (flen - offset) < rlen Then rlen = flen - offset
  dlen = dlen + rlen
  If rlen <= 0 Then exit do
Loop
%>
■ クライアントサイドでDownLoadメソッドを使う
JScrptで DownLoadメソッドを使うダウンロードのサンプルを以下に示します。
----------------- download09.html -------------------------------------------
<HTML><HEAD>
<TITLE>BASP21 Pro Auto Download</TITLE>
<BODY onLoad="download()">
<OBJECT ID="bobj" CLASSID="CLSID:EC0C18A0-4D5E-11D4-896C-00000E4E0AD6">
  <PARAM NAME="Env" VALUE="env1">
</OBJECT>
<SCRIPT language="JavaScript">
function download() {
  bobj.ShowDialog = 3;
  bobj.DownLoad("http://basp21.com/data/log.lzh",bobj.home + "\\log.lzh");
  MSG.innerText = "Done. rc=" + bobj.Result;
}
</SCRIPT>
<P ID="MSG">DownLoading....</P>
</BODY></HTML>
注意:innerTextプロパティ(DHTML)は、IE 4.0 以上で動作します。 IE 3.02はDHTMLをサポートしていません。

DownLoadメソッドでSSL暗号化通信機能を使うには URLパラメータに "http://"の代わりに "https://"を指定します。
rc = bobj.DownLoad("https://www.basp21.com/secure/excel.xls","c:\secret","")

■ ファイルダウンロード+日本語コード変換

DownLoadメソッドの第3パラメータにコード変換 オプションを指定するとダウンロードと同時にコード変換します。
JScrptで ダウンロードファイルをSJISコードに変換するサンプルを以下に示します。
----------------- download10.html -------------------------------------------
<HTML><HEAD>
<TITLE>BASP21 Pro Auto Download</TITLE>
<BODY onLoad="download()">
<OBJECT ID="bobj" CLASSID="CLSID:EC0C18A0-4D5E-11D4-896C-00000E4E0AD6">
  <PARAM NAME="Env" VALUE="env1">
</OBJECT>
<SCRIPT language="JavaScript">
function download() {
  bobj.ShowDialog = 3;
  bobj.DownLoad("http://basp21.com/data/logeuc.txt",bobj.home + "\\log.lzh","-j sjis");
  MSG.innerText = "Done. rc=" + bobj.Result;
}
</SCRIPT>
<P ID="MSG">DownLoading....</P>
</BODY></HTML>

■ IEでShowDialogを使わずに進捗状況を表示したい

進捗状況を表示するには、 OnProgressイベントを使うと可能です。 OnProgressイベントプロシジャは、第1引数にShowDialogプロパティで ダイアログに表示される情報をCRLFで区切って返します。 ここでは、DownLoadメソッドを使ってプログレスバーを文字で表示する サンプルを紹介します。
VBScriptで ダウンロード状況をページ内に表示するサンプルを以下に示します。
----------------- nodialog01.html -------------------------------------------
<HTML><HEAD>
<TITLE>BASP21 Pro Auto Download With Event</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<BODY bgcolor=#000000 TEXT=#ffffff>
<OBJECT ID="bobj" CLASSID="CLSID:EC0C18A0-4D5E-11D4-896C-00000E4E0AD6">
  <PARAM NAME="Env" VALUE="env1">
</OBJECT>
<SCRIPT LANGUAGE="VBScript">
Dim bar,barsize
Sub Window_OnLoad()
  bar = 0: barsize = 30     ' プログレスバーの単位
  bobj.FireEvent = 1
  bobj.DownLoad "http://www.basp21.com/data/log.lzh",bobj.home
  rc = bobj.Result
  If rc = -2 Then
    PROGRESSBAR.innerText = "canceled. "
  Else
    PROGRESSBAR.innerText = rc
  End If
End Sub
Sub bobj_OnLog(log)
   status = log
End Sub
Sub bobj_OnProgress(msg,total,current)
   Dim line,wk,per,i,j
   line = Split(msg,vbCrLf)
   i = InStr(line(2),"%")
   wk = Mid(line(2),i-2,2)
   per = wk / (100 / barsize)
   per = Int(per)
   If bar <> per Then
      bar = per
      progress = ""
      For i = 0 To bar -1
        progress = progress & "■"
      Next
      For j = i To barsize -1
        progress = progress & "□"
      Next
      PROGRESSBAR.innerText = progress
   End If
   MSG0.innerText = line(0)
   MSG1.innerText = line(1)
   MSG2.innerText = line(2)
   MSG3.innerText = line(3)
End Sub
Sub cbtn_OnClick()
  bobj.Cancel()
End Sub
</SCRIPT>
<P ALIGN=CENTER>
<INPUT type="button" NAME="cbtn" value="Cancel">
</P>
<P ID="MSG0"></P>
<P ID="MSG1"></P>
<P ID="MSG2"></P>
<P ID="MSG3"></P>
<P ID="PROGRESSBAR"></P>
</BODY></HTML>
JScriptでのサンプルです。
----------------- jnodialog01.html -------------------------------------------
<HTML><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<TITLE>BASP21 Pro Auto Download With Event</TITLE>
<BODY onLoad="download()" bgcolor=#000000 TEXT=#ffffff>
<OBJECT ID="bobj" CLASSID="CLSID:EC0C18A0-4D5E-11D4-896C-00000E4E0AD6">
  <PARAM NAME="Env" VALUE="env1">
</OBJECT>
<SCRIPT LANGUAGE="JavaScript">
var bar,barsize;
function download() {
  bar = 0; barsize = 20;   // プログレスバーの単位
  bobj.FireEvent = 1;
  bobj.DownLoad("http://www.basp21.com/data/log.lzh",bobj.home);
  var rc = bobj.Result;
  if (rc == -2)
    PROGRESSBAR.innerText = "canceled. ";
  else
    PROGRESSBAR.innerText = rc;
}
</SCRIPT>
<SCRIPT FOR="bobj" EVENT="OnLog(log)" LANGUAGE="JavaScript">
   status = log;
</SCRIPT>
<SCRIPT FOR="bobj" EVENT="OnProgress(msg,total,current)" LANGUAGE="JavaScript">
   var line,wk,per,i,j;
   line = msg.split(unescape('%0D%0A'));
   i = line[2].indexOf("%");
   wk = line[2].substr(i-2,2);
   per = wk / (100 / barsize);
   per = Math.ceil(per);
   if (bar != per) {
      bar = per;
      var progress = "";
      for (i = 0;i < bar;i++) progress = progress + "■";
      for (j = i;j < barsize;j++) progress = progress + "□";
      PROGRESSBAR.innerText = progress;
   }
   MSG0.innerText = line[0];
   MSG1.innerText = line[1];
   MSG2.innerText = line[2];
   MSG3.innerText = line[3];
</SCRIPT>
<P ALIGN=CENTER>
<INPUT type="button" value="Cancel" onclick="bobj.Cancel()">
</P>
<P ID="MSG0"></P>
<P ID="MSG1"></P>
<P ID="MSG2"></P>
<P ID="MSG3"></P>
<P ID="PROGRESSBAR"></P>
</BODY></HTML>

■ Ajaxを使ったアップロード時のプログレスバーの表示

Ajaxを使ったプログレスバーを別ウィンドウで表示するサンプルです。 ASPでも簡単に以下の機能を実現可能です。IEだけでなくFirefox でも動作します。 以下の5つのファイルを使用します。
- upload2.html ... メインのHTML。TYPE=FILEを含むFORMを配置します。
- progwin.asp ... プログレスバーを表示するウィンドウで開くASPファイル。
- afileup.asp ... Request.BinaryReadとFormSaveAsメソッドでファイルを保存するASPファイル。
- progress.asp ... 進捗状況を返すASPファイル。progwin.aspからAjaxで非同期に繰返し(setTimeout)呼ばれます。
- loader.gif ... ローディングイメージ(http://www.ajaxload.info/ でダイナミックに作成可能)。




----------------- upload2.html -------------------------------------------
<html><head>
<title>FileUpload</title>
</head><body>
<script type="text/javascript">
function start_upload() {
  var filenamepara = "";
  filenamepara = escape(document.forms["form"]["file001"].value);
  if (filenamepara == null || filenamepara == "")
      return false;
  var url = "progwin.asp?fname=" + filenamepara;
  document.forms["form"]["submit"].style.visibility = "hidden";
  window.open(url,"Progress",
  "toolbar=no,location=no,directories=no,status=yes,scrollbars=no,resizable=no,width=360,height=180")
  return true;
}
var count = 0;
function setTable(fname,size,time) {
 var tabid = 'uploadTable';
 var targetTable = document.getElementById(tabid);
 var row = targetTable.insertRow(count+1);
 count = count + 1
 var cell = row.insertCell(-1);
 var text = count;
 cell.appendChild(document.createTextNode(text));
 cell = row.insertCell(-1);
 cell.appendChild(document.createTextNode(fname));
 cell = row.insertCell(-1);
 cell.appendChild(document.createTextNode(size));
 cell = row.insertCell(-1);
 cell.appendChild(document.createTextNode(time));
}
</script>
<form id="form" action="afileup.asp" target="upload_frame"
         enctype="multipart/form-data" method="post"
         onsubmit="start_upload()">
  <input type="file" name="file001" value="Upload File">
  <input type="submit" name="submit" value="Upload">
</form>
<iframe name="upload_frame" style="display:none;"></iframe>
<table id="uploadTable" style="visibility:visible">
<tr bgcolor="#cccccc">
  <th>#</th>
  <th>ファイル名</th>
  <th>サイズ</th>
  <th>ロード時間(秒)</th>
 </tr>
</table>
</body>
</html>
----------------- progwin.asp -------------------------------------------
<%@ Language=VBScript EnableSessionState=False %>
<%
fname = Request.QueryString("fname")
fname = Replace(fname,"\","\\")
%>
<html><head>
<title>FileUpload</title>
<style type="text/css">
  BODY{font-size:10pt;}
</style>
</head>
<body onLoad="start_upload()" bgcolor="#eeeeee">
<script type="text/javascript">
  var status = "";
  var errcount = 0;
  function ajax_show_upload_status(status) {
    var now = new Date();
    var sec_time = parseInt((now.getTime() - starttime.getTime()) / 1000);
    var ar = status.split("/");
    var persent = parseInt(ar[0]);
    if (persent < 0) {
      if (errcount < 1) {
        setTimeout('callajax()', 1000);
      }
      errcount = errcount + 1;
      return true;
    }
    var nowsize_kb = parseInt(ar[1]);
    var totalsize_kb = parseInt(ar[2]);
    if (persent >= 100 || totalsize_kb == 0 ) {
      document.getElementById("img").style.visibility = "hidden";
      document.getElementById("estimate").innerHTML="アップロード時間:" +
              sec_time + "秒 " + parseInt(persent/1024/1024) + "MB ";
      if( window.opener && !window.opener.closed ){
        window.opener.setTable(filename,persent,sec_time)
        window.opener.document.forms["form"]["submit"].style.visibility = "visible";
      }
      if (document.forms["closeform"]["closeflag"].checked)
        window.close();
      return;
    }
    var remain_kb = totalsize_kb - nowsize_kb;
    var parsec_kb = parseInt(nowsize_kb / sec_time);
    var remain_sec = "";
    if (parsec_kb > 0) {
       remain_sec = parseInt(remain_kb / parsec_kb);
       document.getElementById("estimate").innerHTML="推定残り時間:" + remain_sec + 
                            "秒 (" + parseInt(nowsize_kb/1024) + 
                            "MB/" + parseInt(totalsize_kb/1024) + "MB) " + persent + "%";
       var parsec_mb = parsec_kb/1024;
       document.getElementById("transferrate").innerHTML="転送率:" + parsec_mb.toFixed(2) + "MB/秒";
    }
    document.getElementById("progressBar").style.display = "block";
    if (persent > 0) 
      document.getElementById("progressBarBoxContent").style.width =
                                       parseInt(persent * 3.5) + "px";
    setTimeout('callajax()', 1000);
    return true;
  }
var filename = "";
var filenamepara = "";
var starttime = null;
function start_upload() {
  starttime = new Date();
  status = "";
  errcount = 0;
  filename = "<%= fname %>";
  document.getElementById("filename").innerHTML = "ファイル名:" + filename;
  filenamepara = escape(filename);
  if (filenamepara == null || filenamepara == "")
      return false;
  document.getElementById("progressBarBoxContent").style.width =0;
  document.getElementById("img").style.visibility = "visible";
  setTimeout('callajax()', 2000);
  return true;
}
var xmlhttp = null;
function createXMLHttpRequest()
{
  var httpreq;
  try {
    if (window.XMLHttpRequest) {
      httpreq = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
      httpreq = new ActiveXObject("Msxml2.XMLHTTP");
      if (!httpreq) {
        httpreq = new ActiveXObject("Microsoft.XMLHTTP");
      }
    }
  } catch (e) {}
  return httpreq;
}
function callajax() {
  xmlhttp = createXMLHttpRequest();
  if (xmlhttp) {
    xmlhttp.onreadystatechange = setPageData;
    var now = new Date();
    var time = parseInt(now.getTime());
    var url = 'progress.asp?fname=' + filenamepara + "&t=" + time;
    xmlhttp.open('GET', url);
    xmlhttp.send(null);

  } else {
    alert("cannot get xmlhttp object");
   
  }
}
function setPageData() {
 if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
    status = xmlhttp.responseText;
    ajax_show_upload_status(status);
 }
}
</script>
<style type="text/css">
  #progressBar {padding-top: 5px;}
  #progressBarBox {width: 350px; height: 12px; border:inset; background: #eeeeee;}
  #progressBarBoxContent {width: 0; height: 12px; border-right: 1px solid #444;
                                       background: #00008b;}
</style>
<div id=img STYLE="visibility:hidden"><img src=loader.gif></div>
<span style="line-height:20px;">
<div id="filename"></div>
<div id="estimate"></div>
<div id="transferrate"></div>
</span>
<div id="progressBar" style="display:none;"></div>
<div id="progressBarBox"><div id="progressBarBoxContent"></div></div>
<FORM id="closeform">
<input type="checkbox" name="closeflag" checked>
アップロード完了後に、このダイアログボックスを閉じる
</FORM>
</body>
</html>
----------------- afileup.asp -------------------------------------------
<%@ Language=VBScript EnableSessionState=False %>
<%
starttime = Now()
Server.ScriptTimeout=72000
totalbytes=Request.Totalbytes
bufferlen = 1024 * 1024  ' 1MB
rlen = bufferlen
b=Request.BinaryRead(rlen)
set bobj = Server.Createobject("basp21pro")
bobj.Env = "env1"
fname = bobj.FormFileName(b,"file001")
if InstrRev(fname,"\") > 0 then
  fpath = "c:\temp" & Mid(fname,InstrRev(fname,"\"))
else
  fpath = "c:\temp\" & fname   ' firefox have no path
end if
rc = bobj.FormSaveAs(b,"file001",fpath,totalbytes)  ' say totalbytes to BASP21
rc = bobj.FormSaveAs(b,"file001",fpath,4)
filelen = rc
readlen = rlen
Do While readlen < totalbytes And rc >= 0
  rlen = bufferlen
  On Error Resume Next
  b=Request.BinaryRead(rlen)
  If Err.number <> 0 then
     rc = bobj.FormSaveAs(b,"file001",fpath,6)  ' delete file
     Exit Do
  End If
  On Error Goto 0
  readlen = readlen + rlen
  rc = bobj.FormSaveAs(b,"file001",fpath,5)
  filelen = filelen + rc
Loop
aa = DateDiff("s",starttime,now())
%>
<HTML>
<BODY>
process time: <%= aa  %><BR>
totalbytes: <%= totalbytes %><BR>
readlen: <%= readlen %><BR>
fname: <%= fname %><BR>
fpath: <%= fpath %><BR>
filelen: <%= filelen %><BR>
rc: <%= rc %><BR>
</BODY>
</HTML>
----------------- progress.asp -------------------------------------------
<%@ Language=VBScript EnableSessionState=False %>
<%
set bobj = Server.Createobject("basp21pro")
bobj.Env = "env1"
fname = Request.QueryString("fname")
if instrrev(fname,"\") > 0 Then
    fname = Mid(fname,InstrRev(fname,"\")+1)
end if
fpath = "c:\temp\" & fname
totalbytes = 0
persent = -1
nowsize = bobj.FileCheck(fpath)  ' get current file size
if nowsize > 0 then
  ar = bobj.ReadDir(fpath & "-Length-*")  ' find status file
  if IsArray(ar) then
    totalbytes = Mid(ar(0),InstrRev(ar(0),"-")+1)  ' get total bytes
  End If
  if totalbytes > 0 Then
    persent = int(nowsize*100 / totalbytes)  ' calc persent
  else
    persent = nowsize
  end if
End If
putdata = persent & "/" & int(nowsize/1024) & "/" & int(totalbytes/1024)
Response.AddHeader "Content-Length", Len(putdata)  ' may be faster
Response.AddHeader "ContentType", "text/plain"
Response.Expires = -1
Response.AddHeader "Cache-Control", "No-Cache"  ' say DO NOT cache
Response.AddHeader "Pragma", "No-Cache"
Response.CacheControl = "Private"
Response.Write putdata
Response.End
%>

Ajaxを使ったプログレスバー表示処理では、以下の点にご注意ください。
1. Ajax で非同期に呼ばれる ASPファイルは、EnableSessionState=False を指定しない場合、
  アップロードを処理するASPファイルと異なるIIS仮想フォルダに配置しないと並行処理されません。
2. FormSaveAsメソッドで処理可能なファイルは、1つのみです。
3. FormおよびFormFileNameメソッドは、初回のRequest.BinaryReadメソッドのバイト配列データに
対してのみ実行可能です。
4. 初回のRequest.BinaryReadメソッドのバイト配列データに対しては、
   FormSaveAsメソッドは、処理モード 4 を指定する必要があります。
   2回目以降は、処理モード 5 を指定する必要があります。
5. FormSaveAsメソッドの戻り値は、1回の呼出しで書込んだバイト数です。
   FormSaveAsメソッドの戻り値の合計が、ファイルサイズを示します。
6. FormFileSize、FormBinaryメソッドは、使用できません。
7. Request.Totalbytesメソッドの戻り値の大きさだけ、
   Request.BinaryReadメソッドを使ってすべて読込む必要があります。
8. Request.BinaryRead複数呼出し処理対応の FormSaveAsメソッドは、
   バージョン 1,0,806,5 以降でサポートされます。
9. プログレス対応のFormSaveAsメソッドは、
   バージョン 1,0,806,16 以降でサポートされます。
注意 200KB以上のファイルをアップロードできない場合は、IISの設定を確認します。
IIS初期設定では、ファイルのアップロードの最大値は、200KBに制限されています。
アップロードの最大値を表示・変更するには、コマンドプロンプトで以下のコマンドを実行します。
cd C:\Inetpub\AdminScripts   ... フォルダ移動
cscript adsutil.vbs get w3svc/aspmaxrequestentityallowed   ... 現在の値を取得

Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

aspmaxrequestentityallowed      : (INTEGER) 204800

cscript adsutil.vbs set w3svc/aspmaxrequestentityallowed 1073741824   ... 値を設定

Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

aspmaxrequestentityallowed      : (INTEGER) 1073741824

iisreset     ... IISを再起動します。

[ホーム] [会社概要] [製品] [サポート]
[BASP21 Pro] [FAQ] [アプリケーションガイド] [ユーザガイド] [リファレンス] [サンプル]
[FTP オブジェクト] [ソケット オブジェクト]

Copyright © 2001-2017 B21Soft, Inc. All Rights Reserved.