TL;DR
- formmethod, formaction 属性使え
- GETリクエストにCSRFトークンが乗ってしまう問題は、2019時点でJSなしではたぶん解決不可能
- ajax?なにそれおいしいの?
経緯
-
「条件を入力して帳票出力する」系の機能で、同一form内に複数のsubmitを共存させたくなった
-
HTMLプレビュー
- ブクマしたいので
GET /preview?検索条件
- ブクマしたいので
-
CSVダウンロード
- ブクマする必要はなく、慣例的にも
POST /download
- ブクマする必要はなく、慣例的にも
-
- POSTが絡むのでCSRFトークン必須
- 何も考えずに実装すると、GETリクエストにもCSRFトークンが乗ってしまう
やったこと
-
form
とCSRFトークンはWebフレームワーク(Laravel 5.5 LTS)に作らせる- CSRFトークンは
input[type=hidden][name=_token]
- CSRFトークンは
-
form
の中にbutton[type=submit]
を複数配置し、下記属性を設定- formmethod属性: 所属しているformタグのmethod属性値をオーバライド
- formaction属性: 所属しているformタグのaction属性値をオーバライド
- このままではGETリクエストにも
_token
が乗ってしまうので、submitボタン押下時に除去するように
$(function () {
// GETリクエスト時はCSRFトークン除去
$('[formaction]').on('click', function (event) {
if (event.target.getAttribute('formmethod') === 'get') {
$('[name=_token]').remove()
}
});
});
考えうる別解
-
formタグはCSRFトークンなしで作り、POSTのsubmit押下時にmetaタグ等から取ってくる
-
ajax
- formのsubmit機能を使わない
所感
-
emacsのeww(テキストブラウザ)をけっこう利用している民としては、これくらいJSに頼らずHTMLだけで完結できてほしいものである
- HTML5でformmethod属性を策定するときに気づかなかったのかなあ