ホーム > タグ > jQuery
jQuery
Rails に XML をボディとするリクエストを JavaScript で送る
- 2011年11月17日 10:03 PM
- 未分類
Rails における XML でのリクエスト
Rails に、Content-Type: application/xml で、ボディが XML のリクエストを送ると、コントローラ中では params に展開される。
# リクエスト
# ヘッダはいろいろ省略してます
POST /entries HTTP/1.1
Content-Type: application/xml
<?xml version="1.0" encoding="UTF-8"?>
<entry>
<body>New blog entry</body>
</entry>
# EntriesController
def create
p params # => {"entry" => {"body" => "New blog entry"}, ...
...
これは主に ActiveResource のための仕様だろうが、XML によるレコードのエクスポートとインポートを行う目的で、同じインターフェイスを HTML から使いたいと考えた。
JavaScript によるリクエスト
HTML の form で Content-Type を application/xml にすることはできない (よね?) ので、jQuery を使って JavaScript で送る。
// url に URL 文字列、
// xml に XML 文字列が格納されているものとする。
$.ajax({
type: "POST",
url: url,
dataType: "xml", // Accept ヘッダをセットする。レスポンスを XML で受けとるなら必要。なくてもよい。
contentType: "application/xml", // Content-Type を XML にする
data: xml,
success: function(res, type) { alert(res); },
error: function(req, message, error){ alert(error); },
});
しかし、HTTP メソッドが GET 以外の場合、リクエストに含まれる authenticity_token をチェックし、無いか session[:authenticity_token] と一致しないと、session が空になってしまう (※)。
これは具合が悪いので authenticity_token を送信する方法を考える。
※ ApplicationController などで protect_from_forgery メソッドが呼ばれている場合。普通呼ばれてます。
CSRF プロテクショントークンを送る
form_for で作ったフォームには authenticity_token が hidden フィールドで格納されているので、そのまま submit すればよい。また、Ajax 通信でも、JSON で送るなら、送信するオブジェクトに authenticity_token プロパティを付与すればよい。この場合 authenticity_token は meta タグから取得する。
<!-- 最近の Rails (3 以降?) なら application.html.erb の head 要素にこんな記述があるはず -->
<%= csrf_meta_tag %>
<!-- これにより下記のような meta 要素が生成される -->
<meta content="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" name="csrf-token">
// jQuery でこれを取得する
var csrf_token = $("meta[name=csrf-token]").attr("content");
しかし、XML はルート要素が 1 つと決められているし、ルート要素は params の 1 要素に納められてしまうため、リクエストボディに authenticity_token を含めることはできない。
そこで、authenticity_token をチェックしているコードをみてみる。
# actionpack/lib/action_controller/metal/request_forgery_protection.rb
def verified_request?
!protect_against_forgery? || request.get? ||
form_authenticity_token == params[request_forgery_protection_token] ||
form_authenticity_token == request.headers['X-CSRF-Token']
end
どうやら X-CSRF-Token ヘッダにトークンを書いてもいいらしい。
jQuery.ajax は beforeSend オプションで、XMLHttpRequest オブジェクトを変更できるので、XMLHttpRequest.setRequestHeader() を使って X-CSRF-Token ヘッダを追加する。
var csrf_token = $("meta[name=csrf-token]").attr("content");
$.ajax({
type: "POST",
url: url,
dataType: "xml", // Accept
contentType: "application/xml",
beforeSend: function(xhr) {
// X-CSRF-Token ヘッダのセット
xhr.setRequestHeader("X-CSRF-Token", csrf_token)
},
data: xml,
success: function(res, type) { alert(res); },
error: function(req, message, error){ alert(error); },
});
これで OK。
PDFへのリンクにアイコンを表示するGreasemonkeyスクリプト
- 2009年8月18日 1:20 AM
- 未分類
PDFへのリンク、嫌ですよね。非力なマシンで対策(PDF Downloadとか)もなくクリックしてしまった日にゃ、「PDFトラップ」なんて言葉も思い浮かぶってものです。
でも、なぜか、官公庁はPDF大好きだし、それもHTMLへのリンクと同じように並んでたりするからタチが悪い。
そこで、ひと目でPDFへのリンクがわかるようになるGreasemonkeyスクリプトを作成しました。
これを導入して、たとえば、厚生労働省のWebサイトを見てみましょう。
まずはbefore。
つづいてafter。
「緊急情報」に隠されたPDFトラップが白日の下に! アイコンちっちゃく見えるかもしれないけど、実際使ってみると十分なサイズですよ。
処理としては、a要素のhref属性が「.pdf」で終わってたら、アイコンを追加するという簡単なもの。URLが.pdfで終わってない場合は無力です。
ただし、適用範囲がhttp通信のWebページ全部と広すぎるので、場合によって適用範囲を制限してください。
Naxos Music Library にIMSLPの楽譜を検索するアイコンを追加するGreasemonkeyスクリプト
- 2009年7月28日 3:18 AM
- 未分類
日々愛用の(主に)クラシック音楽配信サービス Naxos Music Library。
音楽を聴きながら楽譜が見れればいいなと思って、パブリックドメインの楽譜を収集・公開しているIMSLPを検索するGreasemonkeyスクリプトを作成した。
こんな感じで表示され、虫眼鏡アイコンをクリックすれば、(運がよければ)IMSLPの作品ページに飛ぶ。
中身はかなりおおざっぱで、Naxos Music Library に載っているラテン文字のタイトルを、Googleでsite:imslp.org内を検索するリンクを作成(調名が入ってるとヒットしづらい場合があったので、調名は削除している)。その際に I’m feeling luckey が働くようにリンクを作り、Googleのページを経ずにIMSLPにリダイレクトするようにする。
もちろん、Googleの検索が100%ではないし、I’m feeling luckey の精度も信頼できるものではないが、それでもIMSLPに楽譜があれば、8割くらいヒットすると思う(そしてIMSLPの充実ぶりに驚く。もちろん近現代は少ないけど)。
I’m feeling luckey のリダイレクトが邪魔、という人は、39行目をコメントアウト(行頭に//を書く)、または行ごと削除してしまえば、Googleの検索結果ページへ飛ぶ。
今回、楽しようと思って、jQueryを使った。GreasemonkeyでjQueryが使えると20倍は速くスクリプト書けるね(単に私がJavaScriptのDOM操作に慣れてないからか)。参考というか丸写しにしたのが下記ページ
まあしかし、いつものことながらニッチだなあ・・・。
CakePHPで jQuery Star Rating Plugin を使う。
- 2009年2月18日 12:02 AM
- 未分類
今回の記事は、CakePHPで jQuery Star Rating Plugin を使いたい人にしか役に立たない情報です。ニッチです。
いまCakePHPでWebアプリケーションを作ってて(趣味です)、スターレイティングを導入しようと思い、いくらか調べて、「jQuery Star Rating Plugin」が良さそうという結論に達した。
で、さっそく実装して試してみてたら、inputのnameがサンプルのままの「star」だと問題なく動作するんだけど、CakePHPのdata[モデル名][カラム名]の形式のnameにすると、表示もPOSTもうまくいかない。
調べてみると、jquery.rating.js は、inputのnameをもとにクラスやなんかを作るんだけど、そのさいに[ ]をエスケープしてる。
//99行目
var n = (this.name || 'unnamed-rating').replace(/\[|\]/, "_");
まずこのエスケープがまずくて、最初の一個めしか置換してくれないので、直す。
//gオプションを追加
var n = (this.name || 'unnamed-rating').replace(/\[|\]/g, "_");
で、値をPOSTするためにhiddenのinputを作ってる。
//111行目
$.rating.groups[n].valueElem = $('<input type="hidden" name="' + n + '" value=""' + (settings.readOnly ? ' disabled="disabled"' : '') + '/>');
ここはエスケープしちゃうとCakePHPで$this->dataでアクセスできないので、エスケープする前の名前にする。
//さっきのnの宣言部からエスケープ前の名前をもってくる
$.rating.groups[n].valueElem = $('<input type="hidden" name="' + (this.name || 'unnamed-rating') + '" value=""' + (settings.readOnly ? ' disabled="disabled"' : '') + '/>');
これでテストしたら、表示・挙動・POSTデータいづれも問題なさそうだった。コードを熟読してないので問題あるかもだけど。
・・・とまあ、ここまで書いといて気づいたんだけど、jQuery Star Rating Plugin ってGPL(と MIT License)なんですね。フリーだと思い込んでたよ。Webアプリケーションのソース公開はセキュリティ上問題ありそうだしなあ。同じようなの作るのめんどくさいなあ・・・。Creative Commons や MIT License なんかに比べるとGPLやLGPLって制限厳しいくせに線引きがあいまいすぎて、どうも好きになれない。
ホーム > タグ > jQuery
- 検索
- フィード
- メタ情報



