ホーム
ホームページ
更新履歴
NOW!
チャット
ボイスチャット
ボイスメール
分身一覧
中継一覧
チャットメンバー
MSサポート情報検索
検索ページ
システム概要
パスワード変更
システム概要
ダウンロード
フォロー
一覧
WINTIS97
ツール、TIPS
Urlコンポーネント
Sessionモニタ
Excel作成
webinfo
きゃらメール
delold.vbs
rentoday.vbs
ASP TIPS
IRC伝言サービス
IRC計算サービス
プロファイル aspProfile
時間計測 TimeTool
MIMEマップ操作
電話番号11桁対応
ServerVariables
IPアドレス設定
Mediaモニタ
数式電卓
ファイル表示
CHOCOA URL紹介
お勧め
ソフトウェア
ハードウェア
リンク
WinNT WebRing
サイト一覧
前へ
次へ
ランダム
|
ファイルを表示する ASP ページです。
たとえば、
http://www.kawabata.com/view/view.asp?FILE=home1.jpg
とすると、hello.jpg ファイルを表示します。
ファイルを直接URL指定させず、なんからの条件処理をしたい場合や、
ファイルのアクセス数をリアルタイムにカウントしたい場合などに
利用できます。
また、このスクリプトでは、ファイルの最終更新日を利用して、
ファイルが更新されていない場合に、キャッシュが利用されるように
しています。
ファイル
view.asp
必要ファイル
Babaさんの開発されたBASP21.DLL が必要です。
Basp21.DLL の BinaryRead メソッドを利用しています。
使い方
view.asp を IIS のディレクトリに配置します。
view.asp の中の 3行目
Const strBase = "
D:\kawabata\wwwroot\webcam32\"
を適切なディレクトリ名に変更します。
注意:このディレクトリ以下のファイルは、すべてアクセスできるようになります。
したがって、C:\ とすることは、危険です。
これで、設定は終了です。
http://server/view.asp?FILE=ファイル名
と指定してください。
サブディレクトリを指定する場合は、
http://server/view.asp?FILE=パス/ファイル名
と、スラッシュで区切ってください。
対応する拡張子
拡張子と、ContentType の組み合わせは、ContentTypeExt 関数で定義しています。
必要に応じて拡張してください。
ユーザー認証への対応
ユーザー認証した場合のみ、ファイルを表示したい場合は、
認証確認後、ResponseFile関数を呼び出すようにしてください。
たとえば、正しく認証している場合、Session("USERNAME") にユーザー名が
入っている場合には、
If Session("USERNAME") = "" Then
Response.Write "ログオンしていません"
Response.End
End If
If ResponseFile(strBase) > 0 Then
Response.End
End If
などが、考えられます。
キャッシュ対応
このASPでは、HTTP/1.1で規定されたキャッシュ制御機能のうち、
HTTP ヘッダーで定義する Last-Modified と If-Modified-Since を
利用しています。
まず、view.asp は、ファイルを出力する場合、HTTP のレスポンス・ヘッダーに
Last-Modified として、ファイルの最終更新日付を返します。
例:
HTTP/1.1 200 OK
Server: Microsoft-IIS/4.0
Date: Tue, 29 Feb 2000 20:21:42 GMT
Last-Modified: Sat, 17 Jul 1999 22:12:34 GMT
Content-Type: image/jpeg
Cache-control: Private
この後、データが続く
クライアントのブラウザは、このURLに対して、もう一度、表示するときには、
Last-Modified の値を If-Modified-Since として、サーバーに渡します。
例:
GET http://localhost/test/view.asp?FILE=picf0004.jpg HTTP/1.0
Accept: */*
Accept-Language: ja
Accept-Encoding: gzip, deflate
If-Modified-Since: Sat, 17 Jul 1999 22:12:34 GMT
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT)
Host: localhost
Proxy-Connection: Keep-Alive
Pragma: no-cache
Cookie: ASPSESSIONIDQGQQQHFU=JDFDKDPBFGADIILPANNOPELI
view.asp では、ファイルの最終更新日付と、If-Modified-Since の値を
比較して、更新されていれば、ファイルの内容を送信し、
更新されていなければ、次のように、更新されていないという
メッセージのみ返し、ファイルの内容は送信しません。
例:
HTTP/1.1 304 Not Modified
Server: Microsoft-IIS/4.0
Date: Tue, 29 Feb 2000 20:22:16 GMT
Content-Type: text/html
Cache-control: private
したがって、更新されていないファイルを繰り返しサーバーから
ダウンロードすることを防ぐことができます。
これによって、サーバーの負荷の軽減と、クライアントのレスポンスを
向上、回線負荷の軽減を行うことができます。
Proxy キャッシュ対応
このview.asp結果は、それぞれのクライアントには、保存されますが、
Proxy Server のキャッシュには、保存されません。
それは、次のように指定しているためです。
Response.CacheControl = "Private"
Proxy Server に保存してもよい場合は、
Response.CacheControl = "Public"
としてください。
ただし、このようにした場合、セキュリティ認証をしたとしても、
キャッシュ側を参照される可能性があります。
データベースへの応用
今回利用した、Last-Modified と If-Modified-Since は、データベースのページを
ASP から参照する場合にも、利用することができます。
たとえば、特定のレコードの更新日付をレコードのフィールドの値として保存しているので
あれば、この値を Last-Modified として返すことにより、
特定のレコードを WWW 上に表示した結果を効率よく、クライアントに保存し、
また、データベースへの処理を軽減することができます。
画像などのファイルをデータベースに保存している場合にも、利用できます。
ETagとIf-None-Match対応
HTTP/1.1では、Last-Modified と If-Modified-Since と同様な機能として、
ETag と、If-None-Match というヘッダーがあります。
ETag は、コンテンツのバージョンなどをあらわす値です。
サーバーが ETag を返した場合、クライアントは、次回のアクセスから If-None-Match を
つけて、サーバーにアクセスします。
したがって、データベースなどでは、レコードの更新回数などをETag として
送信しておくことにより、より簡単にレコードの更新評価が可能となります。
ファイルが多い場合
更に、活用方法として、ファイル数が1000ファイルを超える場合にも、
利用できます。
たとえば、ひとつのディレクトリに1000以上のファイルを置いておくと、
なにかと管理が難しくなります。たとえば、エクスプローラでフォルダを
開くにも、かなりの時間がかかります。
そこで、ファイルを999個づつ、別々のディレクトリに置いておきます。
ユーザーからは、
http://server/view.asp?FILE=AAAxxx222.jpg
としてアクセスされた場合に、実際のディスクの
D:\AAA\xxx\222.jpg
を参照することができます。
view.asp のチョットした修正で対応できますね。
動作確認
動作確認をするには、HTTPパケットを直接見る必要があります。
手軽に利用できるソフトとしては、秀シリーズの「横取り丸」と「InetSpy」の組み合わせがあります。
小さくて、扱いやすいソフトウェアですので、ぜひお試しください。
http://hide.maruo.co.jp/
このページから、「ソフトウェア」を選択すると、ダウンロードできます。
考察
今回は、JPG ファイルへのアクセスに、認証をかけたいという話から始まりました。
ISAPI で開発することも可能でした。
しかし、BASIC認証やNTLM認証などを使わず、SQLServer上のユーザーテーブルを
利用して認証しているとのことでしたので、ASP で実現しました。
また、ASP で Last-Modified が利用できるかどうかのテストも兼ねています。
お試しいただければと思います。
PDFの場合は、バイトサービング機能により、ページ単位にアクセスされますので、
また別途検討が必要です。
ソース
<%
'--- view.asp
Const strBase = "D:\kawabata\wwwroot\webcam32\"
If ResponseFile(strBase) > 0 Then
Response.End
End If
%>
<html>
<head><title>ファイル表示</title></head>
<body>
ファイル名が指定されていません<BR>
<% = FormatDateHTTP(Now) %>
</body>
</html>
<%
'-----------------------------------------------------------
'--- ファイルを出力する
Function ResponseFile(strBase)
'--- 戻り値の初期化
ResponseFile = 0
'--- 変数宣言
Dim strFile
Dim strPath
Dim strIfModifiedSince
Dim objFileSystem
Dim objFile
'--- オブジェクト宣言
Set objFileSystem = Server.CreateObject("Scripting.FileSystemObject")
'--- Request変数
strFile = Replace(Trim(Request("File")), "/", "\")
strIfModifiedSince = Trim(Request.ServerVariables("HTTP_IF_MODIFIED_SINCE"))
If strFile = "" Then
Exit Function
End If
'--- ファイルオブジェクト取得
strPath = strBase & strFile
On Error Resume Next
Set objFile = objFileSystem.GetFile(strPath)
If Err <> 0 Then
Response.Status = "404 Not Found"
ResponseFile = 404
Exit Function
End If
'--- 更新日付確認
dtmLastModifed = objFile.DateLastModified
strLastModifed = FormatDateHTTP(dtmLastModifed)
If strIfModifiedSince <> "" Then
If StrComp(strLastModifed, strIfModifiedSince, vbTextCompare) = 0 Then
'--- 未修正
Response.Status = "304 Not Modified"
ResponseFile = 304
Exit Function
End If
End If
'--- キャッシュ設定
Response.CacheControl = "Private"
'--- 更新日付出力
Response.AddHeader "Last-Modified", strLastModifed
'--- ContentType 出力
strExt = LCase(objFileSystem.GetExtensionName(strPath))
Response.ContentType = ContentTypeExt(strExt)
'--- ファイルの出力
Set objBasp = Server.CreateObject("Basp21")
If Not IsObject(objBasp) Then
Response.End
End If
baryContent = objBasp.BinaryRead(strPath)
Response.BinaryWrite baryContent
'--- 終了
ResponseFile = 200
End Function
'--- 拡張子からContentTypeを得る
Function ContentTypeExt(strExt)
Select Case LCase(strExt)
Case "jfif", "jpe", "jpeg", "jpg"
ContentTypeExt = "image/jpeg"
Case "gif"
ContentTypeExt = "image/gif"
Case "png"
ContentTypeExt = "image/png"
Case "tif"
ContentTypeExt = "image/tif"
Case "pdf"
ContentTypeExt = "application/pdf"
Case Else
ContentTypeExt = "application/octet-stream"
End Select
End Function
'--- HTTP/1.1 の日付形式(GMT) を返す
Function FormatDateHTTP(ByVal dtmValue)
FormatDateHTTP = ""
If Not IsDate(dtmValue) Then
Exit Function
End If
'--- GMT = JST - 9
dtmValue = DateAdd("h", 9, dtmValue)
'--- Format
FormatDateHTTP = WeekdayNameE(Weekday(dtmValue)) & ", " _
& FormatN(Day(dtmValue), 2) & " " _
& MonthNameE(Month(dtmValue)) & " " _
& Year(dtmValue) & " " _
& FormatN(Hour(dtmValue), 2) & ":" _
& FormatN(Minute(dtmValue), 2) & ":" _
& FormatN(Second(dtmValue), 2) & " GMT"
End Function
'--- 数値を 001 形式と 0 で桁あわせする
Function FormatN(lngValue, lngSize)
FormatN = Right(String(lngSize, "0") & CStr(lngValue), lngSize)
End Function
'--- 英語の曜日名を短縮形で返す
Function WeekdayNameE(lngWeekday)
Dim aryWeekdayName
WeekdayNameE = ""
aryWeekdayName = Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
If lngWeekday < 1 Or lngWeekday > 7 Then
Exit Function
End If
WeekdayNameE = aryWeekdayName(lngWeekday - 1)
End Function
'--- 英語の月名称を短縮形で返す
Function MonthNameE(lngMonth)
Dim aryMonthName
MonthNameE = ""
aryMonthName = Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec")
If lngMonth < 1 Or lngMonth > 12 Then
Exit Function
End If
MonthNameE = aryMonthName(lngMonth - 1)
End Function
%>
|