(in-package :your-cool-app)
(require "xml-http-request")
(use-package :xml-http-request)
;;; 同期 API
(let ((res (xhr-get "http://www.google.co.jp/")))
(msgbox "~S" (xhr-response-text res)))
(multiple-value-bind (response http-status header)
(xhr-get "http://www.google.com/search"
:query '(:hl "ja" :lr "lang_ja" :ie "UTF-8" :oe "UTF-8" :num 50
:q "xyzzy 読み方")
:encoding *encoding-utf8n*
:since :epoch
:key 'xhr-response-values)
(msgbox "~S~%~S" http-status header))
;;; 非同期 API (Future パターン)
(let ((future (xhr-get-future "http://www.google.co.jp/")))
(msgbox "do something~%~S" future)
(let ((res (xhr-future-value future)))
(msgbox "~S~%~S" (xhr-response-text res) future)))
;;; 非同期 API (マクロ)
(with-xhr-post-async ("http://www.excite.co.jp/world/english/"
'(:wb_lp "JAEN" :before "今日雪が降りました。\nテラ寒いです。"))
(on 200 (res)
(when (string-match
"<textarea cols=36 rows=15 name=\"after\".*?>\\([^<>]+?\\)</textarea>"
(xhr-response-text res))
(msgbox "~A" (match-string 1))))
(on :success (res)
(msgbox "成功しました"))
(on :failure (res)
(msgbox "失敗しました... orz"))
(on :complete (res)
(msgbox "終了しました")
(msgbox "~A~%~A" (xhr-response-header res "Server") (xhr-status res))))
;; 非同期 API (関数)
(xhr-post-async "http://search.hatena.ne.jp/questsearch"
'(:wb_lp "ENJA" :before "xyzzy is awesome!")
:oncomplete #'(lambda (res)
(msgbox "終了しました")
(msgbox "http status: ~A" (xhr-status res))
(msgbox "response text: ~A" (xhr-response-text res))))
xml-http-request は HTTP 通信を行うためのライブラリです。 非同期通信を行えるので xyzzy を止めることなく通信できます。
また、Windows が提供する XMLHttpRequest オブジェクトを利用しているため Proxy や Basic 認証、SSL にも対応しています。
Cookie やキャッシュの管理は XMLHttpRequest 内部で行われます。 これらは IE と共有されます。
アーカイブをダウンロードします。
<URL:http://miyamuko.s56.xrea.com/xyzzy/archives/xml-http-request.zip>
xml-http-request は以下のパッケージを利用しています。
xml-http-request
nickname は xhr と msxml です。
なし。
なし。
xhr-errorxhr-open-error指定した URL に接続できない場合に通知されるコンディションです。
非同期 API の時は通知されません。
xhr-too-long-url-error指定した URL が長すぎる場合に通知されるコンディションです。
非同期 API の時は通知されません。
なし。
xhr-get URL &KEY BASIC-AUTH NOMSG KEY SINCE HEADERS QUERY ENCODING指定された URL のリソースを get します。
この API は同期 API です。 get が終了するまでブロックしレスポンスオブジェクトを返します。
BASIC-AUTH には xhr-credential で作成した Basic 認証用の情報を指定します。
(defun gmail-unread (tag user password)
(xhr-get (concat "https://mail.google.com/mail/feed/atom/" tag)
:basic-auth (xhr-credential user password)
:key 'xhr-response-xml
:since :epoch))NOMSG に non-nil を指定するとメッセージを出力しません。
nil の場合メッセージ領域に通信状態を表示します。 デフォルトは nil です。
KEY に関数を指定すると、その関数をレスポンスオブジェクトに適用した結果を返します。
(xhr-get "http://www.google.co.jp/") ;=> #S(xml-http-request::http-response ...) (xhr-get "http://www.google.co.jp/" :key 'xhr-status) ;=> 200
SINCE には送信時の If-Modified-Since ヘッダを指定します。
SINCE には以下の値を指定できます。
HEADERS には送信時の HTTP ヘッダをリストで指定します。
HEADERS に If-Modified-Since を指定し、かつ SINCE も同時に指定した場合は SINCE の指定が有効になります。
QUERY は query string を文字列またはリストで指定します。
指定した query string は URL 中に直接記述している query string とあわせて URL に追加されます。
(xhr-get "http://www.google.com/search?hl=ja&lr=lang_ja"
:query '(:ie "UTF-8" :oe "UTF-8" :num 50
:q "xyzzy 読み方")
:encoding *encoding-utf8n*)
;;=> GET from http://www.google.com/search?hl=ja&lr=lang_ja&ie=UTF-8&oe=UTF-8&num=50&q=xyzzy%20%E8%AA%AD%E3%81%BF%E6%96%B9
文字列を指定するとそのまま URL に追加します。 si:www-url-encode などで適切にエンコードした値を指定してください。
キーと値からなるリストを指定すると自動的にエンコードします。 ENCODING を指定すると文字コードを変換した上で RFC3986 にある程度従い url エンコードします (si:www-url-encode のデフォルトとは違います)。 ENCODING を指定しない場合 Shift_JIS のままエンコードします。
例:
(xhr-response-text
(xhr-get "http://www.google.co.jp/"
;; alist で指定しても ok
:headers '(:User-Agent "Firefox"
:Accept-Language "en, ja")
:since :epoch))
なお、X-Yzzy-Version というヘッダが必ず送信されます (値は xyzzy のバージョン)。
xhr-get-async URL &KEY BASIC-AUTH NOMSG KEY SINCE HEADERS QUERY ENCODING ONSUCCESS ONFAILURE ONCOMPLETE HANDLER指定された URL のリソースを get します。
この API は非同期 API です。 API を呼び出すとすぐに制御を返し、キャンセルオブジェクトを返します。
リクエストを停止したい場合はキャンセルオブジェクトを xhr-abort に指定します。
get が終了すると指定された callback を呼び出します。
BASIC-AUTH NOMSG, KEY, SINCE, HEADERS の指定方法は xhr-get を参照してください。
KEY を指定すると KEY の戻り値がイベントハンドラに指定されます。 KEY が多値を返す場合は、多値の値がイベントハンドラのそれぞれの引数に指定されます。
例:
(xhr-get-async "http://www.google.co.jp/"
:key #'(lambda (res)
(values (xhr-requested-uri res)
(xhr-status res)))
:oncomplete #'(lambda (uri status)
(msgbox "~S => ~S" uri status)))ONSUCCESS
正常終了 (http status が 20x) した場合に呼ばれます。
ONFAILURE
異常終了 (http status が 20x 以外) した場合に呼ばれます。
ONCOMPLETE
通信終了後に常に呼ばれます。ONSUCCESS, ONFAILURE より後に呼ばれます。
HANDLER
HTTP ステータスごとにイベントハンドラを実行したい場合は HANDLER で指定します。
例:
(xhr-get-async "http://www.google.co.jp/"
:headers '(:User-Agent "Mozilla Firefox"
:Accept-Language "ja")
:since :epoch
:oncomplete #'(lambda (res)
(msgbox "~D ~A"
(xhr-status res)
(xhr-status-text res)))
:handler (list
200 #'(lambda (res) (msgbox "OK"))
304 #'(lambda (res) (msgbox "not modified"))
404 #'(lambda (res) (msgbox "not found"))))
なお、X-Yzzy-Version というヘッダが必ず送信されます (値は xyzzy のバージョン)。
xhr-get-future URL &KEY BASIC-AUTH NOMSG KEY SINCE HEADERS QUERY ENCODING指定された URL のリソースを get します。
この API は非同期 API です。 API を呼び出すとすぐに制御を返し、Future オブジェクトを返します。 xhr-future-value で Future オブジェクトから値を取得しようとした時点でまだ get が完了していない場合はブロックします。
リクエストを停止したい場合は Future オブジェクトを xhr-abort に指定します。
例:
(let ((future (xhr-get-future "http://www.google.co.jp/"
:key 'xhr-status-text
:since :epoch)))
(msgbox "do something~%~S" future)
(msgbox "~S~%~S"
(xhr-future-value future :timeout 10)
future))
なお、X-Yzzy-Version というヘッダが必ず送信されます (値は xyzzy のバージョン)。
See Also:
xhr-head URL &KEY BASIC-AUTH NOMSG KEY SINCE HEADERS QUERY ENCODING指定された URL に HEAD リクエストを同期的に送信します。
詳細は xhr-get を参照してください。
xhr-head-async URL &KEY BASIC-AUTH NOMSG KEY SINCE HEADERS QUERY ENCODING ONSUCCESS ONFAILURE ONCOMPLETE HANDLER指定された URL に HEAD リクエストを非同期に送信します。
詳細は xhr-get-async を参照してください。
xhr-head-future URL &KEY BASIC-AUTH NOMSG KEY SINCE HEADERS QUERY ENCODING指定された URL に HEAD リクエストを非同期に送信します。
詳細は xhr-get-future を参照してください。
xhr-post URL DATA &KEY BASIC-AUTH NOMSG KEY SINCE HEADERS ENCODING指定された URL に DATA を同期的に POST します。
DATA は文字列またはリストで指定します。
文字列を指定するとそのまま送信します。 si:www-url-encode などで適切にエンコードした値を指定してください。
キーと値からなるリストを指定すると自動的にエンコードします。 ENCODING を指定すると文字コードを変換した上で RFC3986 にある程度従い url エンコードします (si:www-url-encode のデフォルトとは違います)。 ENCODING を指定しない場合はそのまま url エンコードします。
以下の 2 つの呼び出しは等価です。
(xhr-post "https://www.hatena.ne.jp/login"
"name=foo&password=bar&persistent=1"
:key 'xhr-response-text
:since :epoch)
(xhr-post "https://www.hatena.ne.jp/login"
'(:name "foo" :password "bar" :persistent 1)
:key 'xhr-response-text
:since :epoch)HEADERS で Content-Type が指定されていない場合は application/x-www-form-urlencoded が自動的にセットされます。
(xhr-post url
octet-data
:headers '(:Content-Type "application/octet-stream"))その他の引数および戻り値は xhr-get と同じです。
xhr-post-async URL DATA &KEY BASIC-AUTH NOMSG KEY SINCE HEADERS ENCODING ONSUCCESS ONFAILURE ONCOMPLETE HANDLER指定された URL に DATA を非同期に POST します。
詳細は以下を参照してください。
xhr-post-future URL DATA &KEY BASIC-AUTH NOMSG KEY SINCE HEADERS ENCODING指定された URL に DATA を非同期に POST します。
詳細は以下を参照してください。
xhr-request METHOD URL DATA &KEY BASIC-AUTH NOMSG KEY SINCE HEADERS QUERY ENCODING指定された HTTP METHOD を送信します。 DATA がない場合は nil を指定してください。
その他の引数は xhr-post と同じです。
例:
(xhr-request "OPTIONS" url nil
:key #'(lambda (res)
(split-string (or (xhr-response-header res "Allow") "") #\,)))
;=> ("GET" "HEAD" "OPTIONS" "POST")xhr-request-async METHOD URL DATA &KEY BASIC-AUTH NOMSG KEY SINCE HEADERS QUERY ENCODING HANDLER ONSUCCESS ONFAILURE ONCOMPLETE指定された URL に METHOD を非同期に送信します。
詳細は以下を参照してください。
xhr-request-future METHOD URL DATA &KEY BASIC-AUTH NOMSG KEY SINCE HEADERS QUERY ENCODING指定された URL に METHOD を非同期に送信します。
詳細は以下を参照してください。
xhr-future-p OBJxhr-future-uri FUTURExhr-future-completed-p FUTURExhr-future-value FUTURE &KEY NOWAIT NO-REDRAW SLEEP TIMEOUT INTERVAL指定された Future オブジェクトから結果を取得します。 結果はリクエスト送信時に指定した KEY が適用された結果が返ります。
リクエストが完了していない場合は完了を待ち合わせます。
NOWAIT に non-nil を指定するとリクエストが完了していない場合は 待ち合わせをせずにすぐに nil を返します。
デフォルトは nil です。
NO-REDRAW に non-nil を指定するとリクエストの完了待ち中に 画面の再描画を行いません。
デフォルトは nil です。
SLEEP に non-nil を指定するとリクエストの完了待ち中に キー入力があっても中断しません。
SLEEP が nil の場合キー入力があったら待ち合わせを中断します。 中断時点でリクエスト完了していない場合は nil を返します。
SLEEP を指定した場合は画面の再描画を行いません。
デフォルトは nil です。
TIMEOUT を指定すると指定した秒数以内にリクエストが完了しない場合、 nil を返します。
TIMEOUT に nil を指定するとタイムアウトせずに無限に待ち合わせます。
デフォルトは 3 秒です。
INTERVAL は監視間隔です。
デフォルトは 0.3 秒です。
xhr-requested-uri RES指定されたレスポンスオブジェクトから URI を取得します。
(xhr-requested-uri (xhr-get "http://www.google.co.jp/")) ;=> http://www.google.co.jp/
xhr-all-response-header RESxhr-all-response-header-alist RESxhr-all-response-header-hash RESxhr-response-header RES HEADERxhr-response-text RESxhr-response-xml RES取得した XML を S式で返します。 S 式は xml-parser-modoki と互換性があります(たぶん)。
取得先のリソースが XML でない場合 nil を返します。 XML をテキスト形式で取得したい場合は xhr-response-text を使用してください。
xhr-response-values RESxhr-status RESxhr-status-text RESxhr-abort TRANSPORT指定したリクエストを停止します。
引数には Future オブジェクト (xhr-xxx-future の戻り値)、 キャンセルオブジェクト (xhr-xxx-async の戻り値) を指定可能です。
通信を中断したなら t を返します。 既に通信が終了していたら何もせず nil を返します。
例:
;; 5 秒以内に結果が返らなければコネクションを切断して例外を投げる
(let ((future (xhr-get-future url)))
(let ((v (xhr-future-value future :timeout 5)))
(unless (xhr-future-completed-p future)
(xhr-abort future)
(plain-error "timeout"))
v))xhr-credential USER PASSWORDxml-http-request-version本ライブラリのバージョンを返します。 バージョンは major.minor.teeny という形式です。
それぞれの番号は必ず 1 桁にするので、以下のように比較することができます。
(if (string<= "1.1.0" (xml-http-request-version))
(1.1.0 以降で有効な処理)
(1.1.0 より前のバージョンでの処理))with-xhr-get-async (URL &KEY BASIC-AUTH NOMSG KEY SINCE HEADERS QUERY ENCODING>) &BODY HANDLERxhr-get-async のラッパーマクロです。
マクロの本体には以下の形式でイベントハンドラを記述できます。
(on <(or HTTPステータス :success :failure :complete)> (<仮引数>...)
<イベントハンドラの本体>)
例)
(with-xhr-get-async ("http://www.google.co.jp/" :since :epoch)
(on 200 (res)
(msgbox "200 OK"))
(on :success (res)
(msgbox "成功しました ~S" (xhr-response-header res "Server")))
(on :failure (res)
(msgbox "失敗しました... orz"))
(on :complete (res)
(msgbox "終了しました")
(msgbox "http status: ~A" (xhr-status res))))
on の中身はクロージャに変換されるので以下のようなこともできます。
(setf result (let ((r nil))
(with-xhr-get-async ("http://www.google.co.jp/"
:key 'xhr-response-values)
(on :complete (text status header)
(setf r (list status header text))))
#'(lambda () r)))
(funcall result)with-xhr-head-async (URL &KEY BASIC-AUTH NOMSG KEY SINCE HEADERS QUERY ENCODING) &BODY HANDLERwith-xhr-post-async (URL BODY &KEY BASIC-AUTH NOMSG KEY SINCE HEADERS ENCODING) &BODY HANDLERwith-xhr-request-async (METHOD URL BODY &KEY BASIC-AUTH NOMSG KEY SINCE HEADERS QUERY ENCODING) &BODY HANDLERhttp-get URL &KEY HEADERS ONFAILURE ONSUCCESS ONCOMPLETEこれは互換性のために残されている 非推奨 API です。
変わりに xhr-get、 xhr-get-async を使ってください。
http-post URL DATA &KEY HEADERS ONFAILURE ONSUCCESS ONCOMPLETEこれは互換性のために残されている 非推奨 API です。
変わりに xhr-post、 xhr-post-async を使ってください。
response-text TRANSPORTこれは互換性のために残されている 非推奨 API です。
変わりに xhr-response-text を使ってください。
status TRANSPORTこれは互換性のために残されている 非推奨 API です。
変わりに xhr-status を使ってください。
status-text TRANSPORTこれは互換性のために残されている 非推奨 API です。
変わりに xhr-status-text を使ってください。
abort TRANSPORTこれは互換性のために残されている 非推奨 API です。
変わりに xhr-abort を使ってください。
all-response-headers TRANSPORTこれは互換性のために残されている 非推奨 API です。
変わりに xhr-all-response-header を使ってください。
response-header TRANSPORT HEADERこれは互換性のために残されている 非推奨 API です。
変わりに xhr-response-header を使ってください。
サーバ側が charset を返さずかつ UTF-8 以外の場合は文字化けします。
文字列は xyzzy 内部で Shift_JIS に変換されます。
Shift_JIS 外の文字は ? に化けます (英語と日本語以外はまともに扱えません)。
みやむこ かつゆき (<URL:mailto:miyamuko@gmail.com>)
なし。
xml-http-request は MIT/X ライセンスに基づいて利用可能です。
See xml-http-request/docs/MIT-LICENSE for full license.
xml-http-request 1.2.1 リリース!
xml-http-request 1.2.0 リリース!
各リクエストメソッドに basic-auth 引数を追加しました。
Basic 認証のためのユーザ情報とパスワードを指定します。
(xhr-get "http://foo.com" :basic-auth (xhr-credential "user" "password"))
basic-auth 引数を指定せずに Basic 認証が必要な URI に接続した場合 認証情報を入力するダイアログが表示されます。
1.0.0 〜 1.1.1 では認証ダイアログは表示されません。 0.1 では表示されます。
接続する URL の userinfo に認証情報を指定しても無視される問題を修正 (楓月さんによる報告)
(xhr-get "http://user:password@foo.com")
※ basic-auth 引数を指定した場合は URL の userinfo は無視されます。
xml-http-request 1.1.1 リリース!
xml-http-request 1.1.0 リリース!
xml-http-request 1.0.1 リリース!
xml-http-request 1.0.0 リリース!
xml-http-request 0.1 リリース!