Curl アプレットは通常 Web サイトの一部ですが、アプレットと Web サイトの他の部分とのインタラクションが必要な場合がよくあります。たとえば、次のようなインタラクションが考えれられます。
- サイトからのファイルの読み取り
- フォームを使ってサイトにリクエストを送信
- サイトでブラウザの cookie の使用を設定し、これにアクセスして操作
この章ではアプレットと Web サイトの対話方法について説明します。
注意: この章に掲載されている多くの例は Web サイト上で表示しなければ適切な動作が確認できません。例のコードの下に表示されているリンクをクリックすると、Curl Web サイトで実際の動作を確認することかできます。この章にある対話型の例を実行するには Web サイトへのアクセスが必要であり、したがってインターネット接続が確立されている必要があります。
要約: | - Web サイトからファイルを読み取るのは、ローカル ファイル システムから読み取るのと同じです。
- http: および https: スキーム の URL を使用して Web サーバーのファイルを読みます。
|
Curl® 実行環境 は、ディスクまたは他のリソースからファイルを読むのと同じ方法で Web サーバー上のリモート ファイルの読み取りをサポートします。ローカル ファイルと Web サーバーのファイルの読み取りで唯一異なる点は、ファイルへのアクセスに URL が使用されることです。
http: スキームを使用する URL は、HTTP (Hypertext Transfer Protocol) 経由で Web サーバーから取得されます。
https: を使用する URL は、セキュア HTTP を使用して Web サーバーから取得されます。HTTPS はセキュア ソケット レイヤ (
SSL) ネットワーク接続を使用して、データを暗号化して保護します。詳細は 「
ファイルおよび他のリソースへのアクセス」 を参照してください。
次のコードは Curl ホームページの HTML ソースを読み込んで TextFlowBox に表示します。
{value
let web-buffer:TextFlowBox =
{TextFlowBox width = 5in, border-width = 1pt,
border-color = "black", margin = 2pt
}
let connect-button:CommandButton =
{CommandButton
label = "Get the Curl home page!",
{on Action do
{web-buffer.clear}
let weburl:Url = {abs-url "http://www.curl.com"}
let webdata:#TextInputStream
{try
|| Add the results to the TextFlowBox
set webdata = {read-open weburl}
|| Keep getting stuff until there's no more
{until webdata.end-of-stream? do
{web-buffer.add {webdata.read-one-line}}
{web-buffer.add {br}}
}
catch http-ex:HttpException do
{web-buffer.add
{text
color="red", Some sort of error
occurred connecting to {value weburl}:
{italic {value http-ex.value}}
}
}
finally {if-non-null webdata then {webdata.close}}
}
}
}
{spaced-vbox
connect-button,
{text Results:},
web-buffer
}
}
上の例が Curl の Web サイトで動作しているのを確認することが出来ます。
デモページ から 「
Accessing Files via HTTP」 を選択してください。
HttpFile クラスのメソッドにより、リクエスト メソッドやリクエスト ヘッダーの設定、リクエスト データの送信およびレスポンス ヘッダーへのアクセス機能など、Curl® アプレットをHTTP 上で制御することができます。次の例は前述の例のバリエーションです。この例では、URL のコンテンツの代わりにレスポンス ヘッダーを表示します。
HTTP URL の
read-open は
HttpTextInputStream のインスタンスを返します。レスポンス ヘッダーは
response-headers アクセッサを介して利用できます。同様に、HTTP URL の
read-open-byte は
HttpByteInputStream のインスタンスを返します。
HttpByteInputStream にも
response-headers アクセッサがあります。
次のコードはレスポンス ヘッダーへのアクセスを示しています。
{value
let web-buffer:TextFlowBox =
{TextFlowBox width = 5in, border-width = 1pt,
border-color = "black", margin = 2pt
}
let connect-button:CommandButton =
{CommandButton
label = "Get the Curl home page!",
|| when button is clicked ...
{on Action do
let web-url:Url = {abs-url "http://www.curl.com"}
let http-file:HttpFile =
{web-url.instantiate-File} asa HttpFile
|| open the Url
let web-stream:HttpTextInputStream =
{http-file.http-read-open
|| don't redirect
auto-redirect? = false,
|| return response headers even if error status
always-return-response-headers? = true}
|| display status
{web-buffer.add
"Status: " &
web-stream.response-headers.status}
|| display response headers
{for value:String key name:String in
web-stream.response-headers do
{web-buffer.add {br}}
{web-buffer.add
name &
{if value == "" then
""
else
": " & value}
}
}
{web-stream.close}
web-buffer
}
}
{spaced-vbox
connect-button,
{HBox {text Response Headers:}},
{HBox width=5in, web-buffer}
}
}
上の例が Curl Web サイトで動作するのを確認することが出来ます。
デモページ から 「
Accessing Response Header」 を選択してください。
非特権アプレットのファイル読み取り権限には制限があります。詳細は 「
セキュリティ」 の章を参照してください。
Web サイトとのインタラクションでは、ユーザーが情報を記入するフォームを作成するのが一般的です。フォームの記入が完了すると、ブラウザはフォームのコンテンツ (リクエストと呼ばれます) を Web サイトに送信します。サイトはフォームの情報を受け取ってこれを処理し、検索結果、注文の確認などリクエストの目的に該当する内容を新規のドキュメントに挿入して応答します。ブラウザは次にこの結果を表示し、通常ここでフォームか置き換えられます。
Dialog のサブクラスである
HttpForm クラスを使用して、Curl® 言語で Web フォームを作成することができます。
HttpForm を使用してフォームを作成するのは基本的に
Dialog で作成するのと同じですが、Web フォームの作成には 2、3 の拡張機能が追加されています。ダイアログの使用方法については 「
ダイアログの使用」 を参照してください。この章の以降のセクションでは、ダイアログの使用について理解されていることを前提に説明しています。
リクエストは、get または post のメソッドのいずれかを使用してブラウザから Web サイトに送信されます。get メソッドを使用してリクエストを送信する場合、このリクエストで使用する URL にリクエストのデータがエンコードされます。サーバー側スクリプトは URL からデータを抽出してデコードします。get メソッドはオーバーヘッドが比較的少ないため、フィールド数の少ないフォームによる簡単なリクエストによく使用されます。get メソッドでは大量のデータまたはバイナリ データを処理できません。これは、データのエンコード先の URL にサイズ制限があるからです。
post メソッドはフォームのデータをリクエスト本体にエンコードします。Post リクエストではバイナリ ファイルを含む大量のデータを処理できます。get に比べてこのメソッドは複雑なデコードを行なうため、Web サーバーに送信されるデータやリクエストへの応答によって Web サーバーから送信されるデータの量が増えることになります。
セキュリティ上の理由から、アプレットによる Web サイトへの接続には制限が設けられています。Curl 実行環境 では、コンテンツへのアクセスを許可している Web サイトにのみアプレットから接続することができます。Web サイトは、接続可能なアプレットが記載されている curl-access.txt ファイルを使用してアクセス許可を設定します。
リクエストの送信先になる Web サイトには、アプレットのアクセスを許可する
curl-access.txt を置く必要があります。
curl-access.txt ファイルの説明については、 「
アプレットから Web サイトへのアクセス」 を参照してください。
HttpForm クラスは、web フォームの一部であるコントロールを収めるコンテナの役割を果たします。
HttpForm オブジェクトのインスタンスを作成する際に、リクエストを受信する Web サイト上の CGI プログラムの URL を指定します。
{HttpForm.default form-action:Url, method:HttpRequestMethod=HttpRequestMethod.get, encoding:String=HttpFormData.urlencoded-mime-type, target:String="_self", default-character-encoding:CharEncoding=CharEncoding.ascii, ...}
action パラメータ (CGI スクリプトの URL) のみ必要です。
HttpForm コンストラクタに渡すことができるオプションのパラメータは次のとおりです。
HttpForm オブジェクトに
TextField および
DropdownList などのコントロールを配置して、ユーザーがリクエストの情報を記入できるようにします (コントロールの完全なリストについては下記の 「
フォームの値」 を参照してください)。
name ローカル オプションが設定されたコントロールは、すべてリクエストの一部として Web サイトにコンテンツを送信します。
name 属性は、CGI スクリプトに送信されるパラメータ名として使用されます。リクエストの一部として送信される各コントロールの値は、コントロールの
form-value アクセッサから取得されます。ほとんどのコントロールでは、これはコントロールの
value アクセッサと基本的に同じです。コントロールの値の決定方法の詳細は、「
フォームの値」を参照してください。
注意: HttpForm に追加されるときに
name ローカル オプションが設定されているコントロールだけがリクエストの一部になります。フォームに追加した後でコントロールの
name オプションを設定しても効果はありません。
次のコードは、1 つのフィールドで構成される非常に単純な Web フォームを示しています。
{HttpForm
{url "http://www.curl.com/cgi-bin/list-parameters.pl"},
target="_blank",
{spaced-hbox
{text Your name:},
{TextField name="name"},
{reset-button},
{submit-button}
}
}
上の例のコードで作成されるフォームを次に示します。
このフォームが Curl Web サイトで動作しているのを確認することが出来ます。
デモページ から 「
A Simple Form」 を選択してください。
上の例では、CGI スクリプトは
name と呼ばれる単一フォームのパラメータを受け取ります。このパラメータは、ユーザーが
TextField に入力した値に設定されています。
先に述べたように、
name 属性を持つ
HttpForm 内のすべてのコントロールは、この値をフォームの送信時に Web サイトに送信します。Web サイトに送信される値はコントロールの
value アクセッサではありません。コントロールの
form-value が使用されます。次の表は、
HttpForm 内のコントロールの種類と値の設定方法を示しています。
次の例は、各種コントロールの form-value アクセッサが返す値を示します。
例:
form-value が返す値 |
|
{let text-field-display:TextDisplay = {TextDisplay}}
{let check-button-display:TextDisplay = {TextDisplay}}
{let radio-frame-display:TextDisplay = {TextDisplay}}
{let dropdownlist-display:TextDisplay = {TextDisplay}}
{let listbox-display:TextDisplay = {TextDisplay}}
{let colordropdown-display:TextDisplay = {TextDisplay}}
{HttpForm
{url "http://www.curl.com/"},
{table
width=5in,
{row
{cell TextField:
{TextField
name="name",
{on ValueChanged at t:TextField do
|| Set the display that appears next
|| to the control to the value that would
|| be sent. This has no impact on what would
|| be sent to the server if the form were
|| submitted.
set text-field-display.value =
{if-non-null t.form-value then
t.form-value
else
"null"
}
}
}
}
{cell form-value: {value text-field-display}}
}
{row
{cell
{CheckButton
label="CheckButton",
name="check-button",
check-value="Button Checked",
{on ValueChanged at c:CheckButton do
set check-button-display.value =
{if-non-null c.form-value then
c.form-value
else
"null"
}
}
}
}
{cell form-value: {value check-button-display}}
}
{row
{cell RadioFrame:
{RadioFrame name = "radio-button",
{VBox
{RadioButton radio-value = "Button 1"},
{RadioButton radio-value = "Button 2"},
{RadioButton radio-value = "Button 3"},
{RadioButton radio-value = "Button 4"}
},
{on ValueChanged at r:RadioFrame do
set radio-frame-display.value =
{if-non-null r.form-value then
r.form-value
else
"null"
}
}
}
}
{cell form-value: {value radio-frame-display}}
}
{row
{cell DropdownList:
{DropdownList
name="drop-down-list",
{ListValueItem value="bold", {bold bold}},
{ListValueItem value="italic", {italic italic}},
{ListValueItem value="underline", {underline underline}},
{on ValueChanged at d:DropdownList do
set dropdownlist-display.value =
{if-non-null d.form-value then
d.form-value
else
"null"
}
}
}
}
{cell form-value: {value dropdownlist-display}}
}
{row
{cell ColorDropdown:
{ColorDropdown
name="color-drop-down",
{on ValueChanged at cd:ColorDropdown do
set colordropdown-display.value =
{if-non-null cd.form-value then
cd.form-value
else
"null"
}
}
}
}
{cell form-value: {value colordropdown-display}}
}
{row
{cell ListBox:
{ListBox
height=48pt,
name="listbox",
"Item 1", "Item 2", "Item 3", "Item 4",
{on ValueChanged at l:ListBox do
set listbox-display.value =
{if-non-null l.form-value then
let buf:StringBuf = {StringBuf}
|| Get the strings from the array
{for s:String in l.form-value do
{buf.concat s & " "}
}
{buf.to-String}
else
"null"
}
}
}
}
{cell form-value: {value listbox-display}}
}
{row
{cell {reset-button}}
}
}
}
| |
Curl 言語を使用して Web フォームを作成する利点の 1 つに、サーバーに送信する前にそのデータを簡単にチェックできることがあげられます。可能な範囲のデータ検証をクライアント側で実行することにより、CGI スクリプトが情報の欠落や修正をユーザーに要求するための応答回数を削減することができます。
フォームの最も簡単なデータ検証方法は、送信前にコンテンツの検証が必要な各フィールドで
Commit イベントをキャッチすることです。このイベントは、フォームの送信時に
HttpForm の各コントロールで発生します。コントロールのコンテンツに欠落または誤りがある場合は、フォームが Web サイトに送信されないように例外をスローします。
Web フォーム内のコントロールはすべて
form アクセッサを使用して、これらを格納している
HttpForm オブジェクトにアクセスすることができます。
HttpForm にないコントロールでこのアクセッサを読み取ろうとするとエラーが発生します。このエラーの発生は、特定の Web フォームにボタンを関連付ける必要がないということにつながり、したがって独自のボタンを作成する場合に非常に役に立ちます。
次のコードでは、フォームにコントロールを配置して、送信が許可される前にコントロールがコンテンツを検証します。この例では、フィールドがスローする例外をその他の可能な例外と区別するために、カスタム例外クラスが定義されています。
|| Define an exception that the fields can throw.
{define-class public HttpFieldException {inherits Exception}
{constructor public {default message:String}
{construct-super message}
}
}
{HttpForm
{url "http://www.curl.com/cgi-bin/list-parameters.pl"},
{spaced-vbox
halign="right",
{spaced-hbox
{text Name:},
{TextField
name="name",
|| When user submits the form, check to ensure
|| field has content.
{on Commit at f:TextField do
{if f.value.empty? then
{throw
{HttpFieldException
"Name field must have a value."
}
}
}
}
}
},
{HBox
{reset-button},
{Fill},
{CommandButton
label="Submit",
{on Action at s:CommandButton do
{try
{s.form.submit}
catch e:HttpFieldException do
{popup-message
{text There is a problem with
the form: {value e}.
}
}
catch e:HttpException do
{popup-message
{text An error occurred while submitting
the form: {value e}
}
}
}
}
}
}
}
}
Curl Web サイトで上の例が動作しているのを確認することが出来ます。
デモページ から 「
A Data-validating Form」 を選択してください。
各コントロール自体で検証が行なわれるため、このようなフォームのコンテンツの検証方法には柔軟性があります。さらに、フィールドに新規コントロールを追加する際に送信ボタンのコードを変更する必要はありません。
HttpForm オブジェクト内のコントロールの
form アクセッサを使用して、ユーザーがコントロールに値を入力すると送信されるフォームを作成することができます。たとえば、ユーザーが検索用語を入力して
enter キーを押すと送信される検索フォームを作成することができます。この場合、コントロールが
Action、
ValueFinished、またはその他のイベントを受け取ったときにフォームが送信されるようにします。
次のコードは、ユーザーが enter キーを押すと送信されるアプレット内の検索フィールドを作成する方法を示します。
{HttpForm
{url "http://www.curl.com/cgi-bin/list-parameters.pl"},
margin=4pt,
{spaced-hbox
{text Search:},
{TextField
name="search-term",
{on Action at t:TextField do
{t.form.submit}
}
}
}
}
上の例が Curl Web サイトで動作しているのを確認することが出来ます。
デモページ から 「
A Form Without a Submit Button」 を選択してください。
コントロールの値だけでなく、
HttpForm オブジェクトでは Web サイトへのリクエストとしてファイルのコンテンツを送信することもできます。この機能により、クライアント システムから Web サイトに写真、履歴書やその他のファイルをアップロードするアプレットを作成することができます。
HttpForm がサイトに送信するデータにファイルを追加するには、
add-file メソッドを呼び出してそれにパラメータ名およびファイルの URL を渡します。ファイル名は自動的にファイル データと一緒に送信されます。または、
add-file-data メソッドを呼び出してこれにパラメータ名、ファイル名およびファイルのデータを格納する
{Array-of byte} を指定することによって、バイト配列をファイルとして送信することもできます。このメソッドは、アプレットがすでにファイルをメモリに読み込んでいる場合 (イメージにフィルタが適用されている場合など) に有効です。
ファイル データは URL 内でエンコードできないことから、フォームの一部としてファイルを送信する場合は、post 送信メソッドを使用してコンテンツをマルチーパート エンコーディングでエンコードする必要があります。
次のコードでは、単一のユーザー指定ファイルを含むリクエストの送信フォームを作成しています。ユーザーは送信するファイルを選択するのに
Choose File ボタンをクリックします。このボタンは
choose-file を呼び出し、結果を
file-url 変数に格納します。ユーザーが
Submit ボタンを押すと、フォームの
add-file メソッドが呼び出され、選択したファイルがフォームに追加されます。
|| Holds the URL of the file the user wants to upload
{let my-file-url:#Url}
{let submit-button:CommandButton =
{CommandButton
enabled?=false,
label="Submit",
{on Action do
|| Add the file to the form
{submit-button.form.add-file
"uploaded-file",
|| will not be null when Submit button is enabled
{non-null my-file-url}
}
|| Submit the request
{submit-button.form.submit}
set submit-button.enabled? = false
set submit-button.label = "Submit"
{submit-button.form.reset}
}
}
}
{HttpForm
{url "http://www.curl.com/cgi-bin/file-upload.pl"},
margin=6pt,
method=HttpRequestMethod.post,
encoding=HttpFormData.multipart-mime-type,
{spaced-hbox
{CommandButton
border-style=BorderStyle.raised,
label="Choose File",
|| Ask the user for a file.
{on Action do
set my-file-url =
{choose-file title="Select a file to upload"}
{if-non-null my-file-url then
|| Display the name of the selected file
set submit-button.label = "Submit " & my-file-url.name
set submit-button.enabled? = true
}
}
},
submit-button
}
}
上の例が Curl Web サイトで動作しているのを確認することが出来ます。
デモページ から 「
A Form That Uploads Files」 を選択してください。
前述の Web フォームの例では、リクエストに対する Web サイトの応答はブラウザに返送され、既存のコンテンツ (フォームを含む Curl アプレット) をこれに置き換えています。この応答は通常 HTML ページですが、動的に生成された Curl アプレット、イメージまたはブラウザで処理できるその他のファイルである場合もあります。このリクエストとレスポンスのサイクルは、HTML フォームを使用する場合と基本的に同じです。
より高度なアプリケーションでは、Curl アプレットでリクエストを送信して、結果を同じアプレットに読み取らせることができます。アプレットでは、任意の方法で結果を表示することができます。このメソッドの使用では変更が必要なコンテンツが常に更新されることから、円滑なアプレット環境をユーザーに提供することができます。
次の例では、スクリプトにリクエストを送信して結果を読み取っています。Web サイトからの応答は HTML コードになり、
TextFlowBox に示されます。
例:
リクエストの結果の読み取り |
|
{let results:TextFlowBox = {TextFlowBox}}
{HttpForm
{url "http://www.curl.com/cgi-bin/list-parameters.pl"},
{spaced-hbox
{text Search:},
{TextField
name="search-term",
{on Action at t:TextField do
|| Clear out the results
{results.clear}
|| Send request and read results
let reply:#HttpTextInputStream
{try
set reply = {t.form.submit-open}
{results.add {reply.read-one-string}}
catch e:Exception do
{results.add
{text An error occurred while contacting the
server. The error was {italic {value e.value}}
}
}
}
}
}
}
}
{value results}
| |
|| Create a single String parameter for the request
{let request-param:HttpFormStringParam =
{HttpFormStringParam
"search-query", "curl"
}
}
|| Create the form data and add the parameter to it.
{let my-request:HttpFormData =
{HttpFormData}
}
{my-request.append request-param}
|| Call browse-url-form when user clicks a button
{CommandButton
label="Click me!",
{on Action do
{{get-the-applet}.browse-url-post
|| This is the URL we are sending the request to (usually
|| some sort of CGI script)
{url "http://www.curl.com/cgi-bin/list-parameters.pl"},
my-request
}
}
}
上の例が Curl Web サイトで動作しているのを確認することが出来ます。
デモページ から 「
Directly Querying Web Sites」 を選択してください。
Web サイトでは、クライアント システムのブラウザが cookie と呼ばれる少量の情報を格納するように設定する場合がよくあります。Cookie は HTTP リクエストのヘッダーに定義されます。セッションの識別やユーザー名など、リクエスト間の状態を保持するのに使用されます。HTML ベースの Web アプリケーションでは、Web サーバーへのリクエスト間の状態を保持するのにこの方法を使用するのが一般的です。cookie を使用して、サーバーはクライアントからのリクエストを進行中のセッションに関連付けることができます。
Curl アプレットでは、情報を保持するために cookie に依存する必要がありません。通常、ブラウザは最初にサイトからアプレットをロードし、ユーザーが作業を完了するまでアプレットは実行を続けます。アプレットはセッション間の少量のデータを格納するのに
パーシスタント データを使用し、これによりユーザーが最後にアプレットを実行したときの設定を回復することができます。
ただし、他のページが設定した cookie にアクセスしたり、他のページからアクセス可能な cookie を作成できると便利な場合があります。cookie へのアクセスにより、HTML ベースのサーバー側アプリケーションから Curl ベースのアプリケーションへの移行、またはその逆の移行をシームレスに行なうことができます。
さらに、アプレットは cookie に格納されている既存のデータを利用することもできます。
cookie は HTTP リクエストのヘッダーの一部なので、ブラウザから Web サイトにこれを送信して、HTML ドキュメントだけでなく Web サイト上の任意のファイルをリクエストすることができます。Cookie は、ブラウザがイメージ、データ ファイル、Curl アプレットを要求するとき、または cookie で有効な任意のリクエストに対して送信されます。
ユーザーは、特定のcookieもしくは全てのcookieの受け入れを拒否するようにブラウザを設定していることがあります。あなたのWebアプリケーションが動作する為に、cookieを受け入れてもらうことが必要な場合には、ユーザーにその旨を伝える必要があります。
アプレットは
get-http-cookies プロシージャを使用して、特定の URL をリクエストする際にブラウザが送信する cookie にアクセスすることができます。非特権アプレットの場合は、それ自体の URL のリクエストの一部としてブラウザが送信する cookie リスト、またはアプレットと同じディレクトリにあるファイルの URL にのみアクセスすることができます。セキュリティ対策の詳細は、「
セキュリティ」の章を参照してください。
次のコードでは、アプレット自体の URL をリクエストする際にブラウザが Web サイトに渡す cookie にアクセスします。
|| Get the cookies for this applet's URL.
{let cookies:{Array-of HttpCookie} =
{get-http-cookies
{get-the-applet}.url
}
}
|| Table to list cookies in
{let cookie-list:Visual =
{Table
{row-prototype
font-weight="bold",
"Name",
"Value",
"Expiration"
}
}
}
{if cookies.empty? then
|| There were no cookies
{set cookie-list = {text No cookie for you!}}
else
{for cookie:HttpCookie in cookies do
{cookie-list.add
{row-prototype
cookie.name,
cookie.value,
|| Expires and other fields may return null,
|| If expires means null, then this is a cookie
|| that only lasts until the current session
|| ends (i.e. user closes the browser).
{if-non-null cookie.expires then
cookie.expires
else
{text Session-only}
}
}
}
}
}
{value cookie-list}
上記のコードが Curl Web サイトで動作しているのを確認することが出来ます。
デモページから 「
Getting Cookies」 を選択してください。
いずれの cookie 設定プロシージャも
Url および
HttpCookie を取ります。
Url は有効な cookie の URL です。この URL を使用する任意のリクエスト、または URL で指定されたディレクトリの子ディレクトリからのリクエストに対して、ブラウザは Web サイトに cookie を返信します。URL に Web サイトのルート (すなわち
http://www.example.com/) だけを指定する場合、サイトからのすべてのリクエストに対してブラウザが Web サイトに返す cookie が作成されます。
非特権アプレットについては cookie の取得に関する制限と同様に、アプレット自体を含むディレクトリ以外の URL に対して、cookie を設定することはできません。
{let cookie-name:TextField = {TextField}}
{let cookie-value:TextField = {TextField}}
{let change-it:CommandButton =
{CommandButton
label="Set cookie",
{on Action do
{if not (cookie-name.value.empty? or cookie-value.value.empty?)
then
|| Construct the cookie
let cookie:HttpCookie =
{HttpCookie
cookie-name.value,
cookie-value.value
}
|| Set the cookie so that the browser will
|| submit it to the server for any requests
|| under the applet's directory.
{set-insecure-http-cookie
{get-the-applet}.url,
cookie
}
|| Now load the applet that displays the
|| cookies.
{{get-the-applet}.browse-url
{url "get-cookies.curl"}
}
else
{popup-message
{text You must provide both a cookie name
and a value.}
}
}
}
}
}
|| Lay out the controls.
{VBox
halign="right",
{spaced-hbox {text Cookie name:}, cookie-name},
{spaced-hbox {text Cookie value:}, cookie-value},
{spaced-hbox {Fill},change-it}
}
Curl Web サイトで、上の例が動作しているのを確認することが出来ます。
デモページ から 「
Setting Cookies」 を選択して下さい。
デフォルトでは、アプレットによる全てのHTTPに関連した呼び出しは、アプレットのプロセスで実行されます。この状況下においては、Curlアプレットは、ブラウザとcookieやログイン状態のような情報を共有する限られた能力しか持っていません。アプレットは、インターネット・エクスプローラとのみcookieを共有することが出来、他のブラウザとは共有できません。Curlアプレットは、将来日付の有効期限を持ったcookieのみインターネット・エクスプローラと共有することが出来ます。 このようなcookieはディスクに書き込まれ、アプレットと共有することが出来ます。
Curl RTE と IE7 との間で共有されている HTTP cookie は Vista 上ではそれ以前の Windows のオペレーティング システム上でのようには動作しません。cookie を共有するには、ユーザーは
[Curl コントロール パネル] の
[セキュリティ] タブを使用して web サイトのホストを特権を与えられたホストのリストにくわえなければなりません。この問題についての詳細な説明は、「
Microsoft 社のサポート記事」をご覧ください。
インターネット・エクスプローラ以外のブラウザで実行されているアプレットは、パッケージのインポートやファイルやイメージのインクルードのようなアプレットが実行する全てのHTTPトランザクションのヘッダ内にWebサイトが格納して送るcookieにだけアクセスすることが出来ます。
Webアプリケーションが、CurlアプレットとHTMLベースのページと状態を共有する必要があり、かつインターネット・エクスプローラ以外のブラウザをサポートしなければならない時は、アプレットのダウンロードに使用されるURL内にWebサイトでエンコードされたデータを持たせるか、共有データを含むCurlアプレットを動的に生成することが出来ます。
別の選択肢は、
request-browser-resident-httpプロシージャを使用して、HTTPに関する呼び出しをブラウザのプロセスで実行するように要求することです。Browser resident HTTPをサポートするブラウザでは、全てのHTTP cookie呼び出し、HTTP認証呼び出し、"http:" や"https:"を使用した呼び出しは、Webブラウザと同じcookieと同じ認証情報を使用します。Browser resident HTTP は、インターネット・エクスプローラではフルサポートされますが、他のブラウザにおいては、サポートの範囲が限定されます。
{request-browser-resident-http}
これは、完全な Browser resident HTTPを要求します。Windowsプラットフォームでのインターネット・エクスプローラ上でのみ利用可能です。
- これらの条件に当てはまる場合には:
- これらの条件に当てはまらない場合には:
{request-browser-resident-http BrowserResidentHttpStyle.minimal}
この呼び出しは、最低限の Browser resident HTTPを要求します。 アプレットは現在のブラウザで利用可能なサポートを取得します。
- アプレットがインターネット・エクスプローラで実行されている場合:
- アプレットが他のブラウザで実行されている場合、フルサポートは利用できません。:
- サポートされない場合:
Browser resident HTTP の最低限のサポートは、フルサポートに比べてに明らかに機能が少なくなります。そのサポートの正確なレベルはブラウザ毎に異なります。このセクションでは、それらの制限の幾つかを説明します。
HTTP cookiesを取得、設定する以下のプロシージャは、機能しません。
get-http-cookies は空の配列を返します。他のプロシージャはただ失敗します。
HTTP認証に基づいたAPIを実行する以下のプロシージャは、ただ失敗します。フルサポートの環境下では、これらはユーザー名とパスワードをセットします。最小サポートの環境下では 、これらは動作しません。ユーザー名とパスワードを必要とするリクエストは、ダイアログ・ボックスをポップアップさせて、ユーザー名とパスワードを尋ねます。
レスポンス ヘッダーを取得したり、レスポンス ステータス コードを取得したり、missing file や permission deniedなどの場合のステータス コードに基づく特殊な例外を取得する以下のプロシージャ、メソッドは、幾つかの新しい Webブラウザ上で、時々しか動作しません。レスポンスに現れるヘッダは、Last-Modified、 Content-Length、Content-Type だけです。 Content-Typeには、charset パラメータがありません。 より新しい Webブラウザでは、成功したリクエストの完全なヘッダーを持つ場合があります。古い Webブラウザでは、ステータス コードは、200と404だけです。404は、新しいWebブラウザ上では、他のステータス コードが使われるべき失敗の場合にも使われる時があります。古い Webブラウザでは、HTTPヘッダーに基づいたテキスト ストリームへのCharEncoding の設定もまた動作しません。
以下のメソッドによって、スローされる例外に幾つかの問題があります。HTTPリクエストが失敗した時、例外がスローされます。最低限の Browser resident HTTPでは、例外のスローは必ずしも失敗の本当の理由をあらわしているとは限りません。他のタイプのhttp exceptionを受け取るべきところで、
HttpException や
HttpMissingFileExceptionを受け取る時があります。決して
HttpPermissionDeniedFileExceptionを受け取ることはありません。リクエストが動作している時には例外を受け取ることはありません。 しかしながら、Netscape 4.xのような幾つかのブラウザでは、webサーバーからエラーページを受け取っており、例外を受け取らなければならないような時でも、成功しているように見える時があります。
アプレットから他のページに移動すると、現行のHTTPリクエストはキャンセルされ、例外がスローされます。
以下のメソッドに対して、若干の制限が加えられます:
これらの制限は:
- HEADリクエストは、GETリクエストを行いすぐにそれをキャンセルすることでシミュレートされます。
- request-headersをGETもしくはHEADリクエストに対して設定することは機能しません。always-return-response-headers?をtrue に設定すると何も行いません。
- auto-redirect?パラメータをfalseに設定して、リダイレクションを制御することは機能しません。
- Firefoxのリビジョン1.5未満、Mozillaのリビジョン1.7未満において、オフラインモードは正しく報告しません。
- FirefoxとMozillaの古いバージョン、Netscape6.0以上のリビジョンにおいて
- 見つけられないホスト名を含んだURLを開こうとするとハングします。
- オフラインモードの時、キャッシュに無いURLを開こうとするとハングします。
- Netscape 4.6と 4.7において:
- 存在しないファイルのURLを開こうとすると、Webサーバーからエラーページ コンテンツが返されますが、例外をスローしません。
- オフライン モードでは、HTTPリクエストは動作しません。
- Operaにおいては、アプレットが自分自身のソースコードを読もうとするとハングしたり、オフラインモードで全てのHTTPリクエストが失敗したり、非常に多くの損x財しないファイルをリクエストするとハングするといったように様々なバージョンで様々な問題があります。
最低限の Browser resident HTTP を利用したアプレットをディプロイする時、 このHTTPの実装はファイルのリロードを実行できないという制限に対処する為に、幾つかの追加の処置を行う必要があります。同期の問題に関する一般的な論述は
キャッシュと同期 をご覧ください。
ユーザーが更新された内容をすぐ見ることが出来るようにする為、、アプレットの起動ファイルの有効期限が直ちに切れるようにWebサーバーを設定する必要があります。さらに変更を加えたファイルの名前もしくはディレクトリを変更するか、変更を加えたファイルの有効期限が切れているように設定する必要があります。 起動ファイルやマニフェスト以外の多くのファイルにおいては、有効期限が切れているように設定するよりも、ファイルのパスを変更するのが良い方法です。
ファイルの有効期限は、再同期の前にどれだけの期間そのファイルがキャッシュされうるのかを示す期限を設定します。ファイルがクライアントにキャッシュされてしまうと、その有効期限を設定することはできません。ですからアプリケーションをディプロイする時に有効期限を指定する必要があります。ディプロイする時点で、ファイル内容を変更することがあるかどうか、またどれだけ頻繁に変更することになるのか分からないかもしれません。多くのファイルをすぐに有効期限が切れるようにすると、クライアントとサーバー間で余分な同期を発生させる可能性があります。それは、特に接続が遅い時にかなりの時間を要する可能性があります。有効期限がすぐに切れるように設定したファイルがアプレット自身のみだった場合、そのアプレットは、リロードされる時に無条件で同期されなければならない唯一のものになります。 Curlが、HTTPの呼び出しを自分で行う場合は、 アプレットのresync-as-of属性をそのまま実行することが出来、ディプロイする時にファイル名の変更をする必要はありません。Browser resident HTTPを使う場合には、Curlは、ブラウザに再同期させる方法を持たないので、ディプロイする人は、更新されたファイルを以前にクライアントにキャッシュされたことが無い新しいファイル名に変更するか、または前もって、変更する可能性があるファイルの有効期限が切れるように準備する必要があります。この場合はアプレットが遅くなる可能性があります。
メイン マニフェスト ファイルもまた移動するか有効期限が切れているように設定する必要があります。メイン マニフェスト ファイルが
resync-as-of属性を持っていた場合、その
resync-as-ofの時刻は、アプレットで使用されている何かが変更された時はいつでも更新しなければなりません。マニフェストで
resync-as-of属性を使用している場合は、メタデータに小さな値をセットする
cache-duration属性も追加したくなるかもしれません。そのような
cache-duration属性は、Curl RTEが頻繁にメイン マニフェスト ファイルをチェックするようにします。
cache-durationの設定に関するより詳細な情報については、
パッケージおよびマニフェストでの cache-duration の使用 をご覧ください。
他の方法は、アプレット ファイルの中にresync-as-of属性を記述することです。アプレット ファイルのresync-as-of属性は、アプレットで使用されているパッケージが変更された時は更新されなければなりませんが、最適な同期動作を提供します。アプレット ファイル内のresync-as-of属性は、メイン マニフェスト内のresync-as-of属性をオーバーライドします。IDEディプロイメントは自動的にメイン マニフェスト内のresync-as-of属性を処理しますが、アプレット ファイル内のresync-as-of属性は処理しません。
パッケージのマニフェストや、一緒に使用されるパッケージのライブラリのマニフェストに
delegate-toを使うことも出来ます。マニフェストの委譲を使うと、より効率的に変更されたパッケージだけ更新することが出来ます。画像のようなサポートファイルをロードする為に
manifest-urlを使うと、サポートファイルが移動した時にアプレットやパッケージを変更する必要がありません。いずれの場合でも、全てのマニフェストファイルは、移動するかすぐに期限切れになるように設定しなければなりません。 アプレットもしくはメイン マニフェストが
resync-as-of属性を持っている時には、何らかの変更があった時にはいつでも
resync-as-of属性が更新されなければならないこと覚えておいてください。委譲されたマニフェスト内の
resync-as-of属性は無視されます。
例えば、以下のような構成のアプレットがある時:
appletX
start.curl (直ちに有効期限を切るように設定されています)
manifest.mcurl (直ちに有効期限を切るように設定されています)
packageA
manifest.mcurl (直ちに有効期限を切るように設定されています)
1.0
load.pcurl
packageB
manifest.mcurl (直ちに有効期限を切るように設定されています)
1.1
load.pcurl
image.jpg
packageBを更新したら、以下のように変更します。:
appletX
start.curl (直ちに有効期限を切るように設定されています)
resync-as-of, 使用していたら変更します。
manifest.mcurl (直ちに有効期限を切るように設定されています)
resync-as-of, 使用していたら変更します。
packageA
manifest.mcurl (直ちに有効期限を切るように設定されています)
1.0
load.pcurl
packageB
manifest.mcurl (直ちに有効期限を切るように設定されています)
load.pcurlとimage.jpgのパスを変更します。
1.2
新バージョンの為の新しいディレクトリ名
load.pcurl
目的のコードとバージョンナンバーだけ変更します。
image.jpg
翻訳ファイルの指定で記述されている翻訳ファイルの指定に関するメソッドは、Netscape4.7で最低限の Browser resident HTTPを使うと正しく動作しません。何故ならば、missing fileが期待通りに扱われないからです。この状況においては、パッケージ プロジェクトのマニフェストに記述されなければならないパッケージの翻訳ファイルを記述しなければなりません。
マニフェストを使用した翻訳ファイルの位置付けをご覧ください。
ルート インストーラーにおいて、curl-timestamp.txt とcurl-contents.txt または、curl-archive.car のいずれかが使われている場合、それら全ては、直ちに有効期限が切れるように設定しなければなりません。 もしもcurl-contents.txtファイルが使われている場合は、 通常のディプロイメントの為に削除されたファイルが存在すると、curl-contents.txtの中のリストが変更されます。
モジュール インストーラーにおいて、全てのcurl-modules.txtファイルは、直ちに有効期限が切れるように設定する必要があります。ルート インストーラーと同時に使用する場合には、全てのcurl-timestamp.txt 、 curl-contents.txt 、 curl-archive.car は直ちに有効期限が切れるように設定する必要があります。
Apacheサーバーに推奨された有効期限を設定するには、以下にあげるような行を設定に加えてください。これらの行は、.htaccessファイルまたは、主要設定ファイルの<Directory>セクションに記述してください。マニフェストやアプレットに起動ファイル名に別の名前を使用している場合には、正規表現を修正してください。
# matches curl-contents.txt, curl-modules.txt, curl-timestamp.txt,
# curl-archive.car, manifest.mcurl and start.curl
<FilesMatch "^(curl-(contents|modules|timestamp)\.txt|curl-archive\.car|manifest\.mcurl|start\.curl)$">
ExpiresActive On
# expire immediately
ExpiresDefault A0
</FilesMatch>
IISに設定するには、全てのコンテンツが直ちに有効期限が切れるようにディレクトリのプロパティを設定してください。
Copyright © 1998-2019 SCSK Corporation.
All rights reserved.
Curl, the Curl logo, Surge, and the Surge logo are trademarks of SCSK Corporation.
that are registered in the United States. Surge
Lab, the Surge Lab logo, and the Surge Lab Visual Layout Editor (VLE)
logo are trademarks of SCSK Corporation.