0
jQuery Validation x ASP.NET MVCで遭遇した不具合 & 対抗ハック                      @jsakamoto         Community Open Day         2012
Twitter Hashtag•   よろしければ、        #clrh71 でお願いいたします。    –   #cod2012jp だけだと、全国会場の Tweet と混信しそうなので...    –   本セッション中、MiniTw...
jQuery Validation についておさらい•   クライアント側スクリプトによる入力検証機能を提供する JavaScript    ライブラリ。    –   jQuery のプラグイン•   ASP.NET MVC の、標準のクライ...
本セッションのテーマ•   jQuery Validation を使っている上で ”些細な” 不具合にいくつか遭遇•   それら不具合について紹介、どう対策して解決したのかを披露•   対策はすべて、クライアント側 JavaScript コード...
デモ アプリ•   こんな ASP.NET MVC4 な    Webアプリを肴に、実演を    交えつつ、進めて参ります。
Case 1.  文字数検証 - input type=“text”
Demo
何が起きてる?•   jQuery Validation は、行頭行末の空白を除いた文字数で    チェック    –   ”期待” とは異なったクライアント側検証。•   サーバー側検証では、行頭行末の空白もそのままに文字    数チェックす...
対応•   jQuery Validation の検証メソッドを改変すればいいmaxlength: function(value, element, param) { return this.optional(element) || this....
方法1 - jQuery Validation のソースを直接変更•   MIT License•   でも将来の jQuery Validation 本家のバージョンアップに    ついていける?
方法2 – 開発元にフィードバック•   trim しているのは、それはそれで意味があるのでしょう。•   その上でなお、破壊的変更が受け入れられるのか?•   仮に受け入れられるとして、リリースされるまで待てる?    – “今そこにある危機”
方法3 – 実行時にOverride•   JavaScript なので、実行時に「書き換え」できます。    $.validator.methods.maxlength =      function (value, element, par...
JavaScript コードの Hack•   いかにも “動的言語” らしく、Hack しやすい。•   しかし Closure が使える...!    –   関数型言語っぽい手法で作成されると手が出せない。•   jQuery Valid...
Case 2.  文字数検証 - textarea
Demo
何が起きてる?•   jQuery Validation は、改行は1文字として文字数チェック。•   サーバー側検証では、改行は2文字として文字数チェック。    –   POST データ中、改行が CR+LF になってる    –   Wi...
対応•   サーバー側で CR+LF を LF に置換することで対応可能。•   でも、漏れなく実装するのは大変では?•   それでは jQuery Validation の実装を変更しましょう。    –   オリジナルの $.validat...
実行時に Override         元の実装をorgに確保var org = $.validator.prototype.getLength;                                       getLengt...
Case 3.  Cancel ボタン
Demo
何が起きてる?•   “cancel” CSSクラスを持つ input か button がクリックさ    れると「入力検証しない」のフラグが立つ。•   そしてそのフラグは解除されない。     this       .find("inpu...
正攻法 – input で Cancel ボタンを実装しない•   a 要素で。•   Twitter Bootstrap など昨今の CSS ライブラリを使えば、a も    input も、同じ外観に作れる。
どうしても、という場合...•   「検証しない」フラグをワンショット遅延でオフに復元。    $(".cancel").click(function () {      var validator =        $(this).close...
Case 4.  IE8
Demo
何が起きてる?•   $.validator.elements メソッドの内部に原因•   IE8 だとなぜか、$($(“form”)[0].elements).filter(“:input”)    の結果が、要素数 = 0個になっている  ...
対応 – jQuery Validation を最新に•   この問題を抱えているのは、実は ver.1.8.0.1 まで。•   jQuery Validation を ver.1.8.1 以降に Upgrade で解決。    –   ve...
jQuery Validation を最新にできない場合は...•   $.validator.elements の実装を実行時に Override。•   .filter(“:input”) ではなく、.find(“input, select...
Case 5.  CSS Class 名が検証ルール名にかぶった
Demo
何が起きてる?•   ASP.NET としての入力検証機構とは無関係に、jQuery    Validation による入力検証機構は活きている•   そのひとつ、CSSクラス名による入力検証の発動    –   email    –   re...
jQuery Validation 標準の検証ルールは潰せる•   $.validator.classRuleSettings からCSSクラス名ルールを削除     delete $.validator.classRuleSettings.e...
徒然に
些細なことにこだわってばかりで、自分が器の小さい人間に思えてきました...だって、結局は、サーバー側検証が機能するんだし...
結局、フィードバックは、Microsoft を含め、どこにもしていません。他の仕事とか優先してしまい...どなたか Microsoft Connect とかに投稿いただません?
Web Forms や、MVC2 までのクライアント側入力検証では、些細とはいえ、こんな問題はなかったよな... と思ったり。さすが Microsoft 純正品クォリティ?今振り返るに、jQuery Validation の採用はどうだったんだ...
Thank you...
Upcoming SlideShare
Loading in...5
×

jQuery Validation x ASP.NET MVC で遭遇した不具合 & 対抗ハック

4,254

Published on

Community Open Day 2012 北海道会場 セッション2

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
4,254
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
9
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "jQuery Validation x ASP.NET MVC で遭遇した不具合 & 対抗ハック"

  1. 1. jQuery Validation x ASP.NET MVCで遭遇した不具合 & 対抗ハック @jsakamoto Community Open Day 2012
  2. 2. Twitter Hashtag• よろしければ、 #clrh71 でお願いいたします。 – #cod2012jp だけだと、全国会場の Tweet と混信しそうなので... – 本セッション中、MiniTwitter にて #clrh71 を含む Tweet をポップ アップします。
  3. 3. jQuery Validation についておさらい• クライアント側スクリプトによる入力検証機能を提供する JavaScript ライブラリ。 – jQuery のプラグイン• ASP.NET MVC の、標準のクライアント側入力検証エンジンに採用 – MVC3以降 – Visual Studio にて ASP.NET MVC アプリを新規作成すると標準で使用。• この資料を作成している時点での最新バージョン: – jQuery = v.1.7.2 – jQuery Validation = v.1.9
  4. 4. 本セッションのテーマ• jQuery Validation を使っている上で ”些細な” 不具合にいくつか遭遇• それら不具合について紹介、どう対策して解決したのかを披露• 対策はすべて、クライアント側 JavaScript コード上で施工 – 本セッションの本質的な部分では、C# とか ASP.NET とか出てきません。 – プラットフォーム問わず、Web アプリ共通の話題ではないでしょうか? – っていうか、むしろ、Ruby on Rails などなど、他のプラットフォームでは 問題になってないのか? 気になります。
  5. 5. デモ アプリ• こんな ASP.NET MVC4 な Webアプリを肴に、実演を 交えつつ、進めて参ります。
  6. 6. Case 1. 文字数検証 - input type=“text”
  7. 7. Demo
  8. 8. 何が起きてる?• jQuery Validation は、行頭行末の空白を除いた文字数で チェック – ”期待” とは異なったクライアント側検証。• サーバー側検証では、行頭行末の空白もそのままに文字 数チェックするのでセーフ。 – ”Post Back” な挙動。 – Webではクライアント側検証に頼らないという鉄則。
  9. 9. 対応• jQuery Validation の検証メソッドを改変すればいいmaxlength: function(value, element, param) { return this.optional(element) || this.getLength($.trim(value), element) <= param;} この trim 要らない!
  10. 10. 方法1 - jQuery Validation のソースを直接変更• MIT License• でも将来の jQuery Validation 本家のバージョンアップに ついていける?
  11. 11. 方法2 – 開発元にフィードバック• trim しているのは、それはそれで意味があるのでしょう。• その上でなお、破壊的変更が受け入れられるのか?• 仮に受け入れられるとして、リリースされるまで待てる? – “今そこにある危機”
  12. 12. 方法3 – 実行時にOverride• JavaScript なので、実行時に「書き換え」できます。 $.validator.methods.maxlength = function (value, element, param) { return this.optional(element) || this.getLength(value, element) >= param; };
  13. 13. JavaScript コードの Hack• いかにも “動的言語” らしく、Hack しやすい。• しかし Closure が使える...! – 関数型言語っぽい手法で作成されると手が出せない。• jQuery Validation はそんな実装されてなく良かった... これで学びました。
  14. 14. Case 2. 文字数検証 - textarea
  15. 15. Demo
  16. 16. 何が起きてる?• jQuery Validation は、改行は1文字として文字数チェック。• サーバー側検証では、改行は2文字として文字数チェック。 – POST データ中、改行が CR+LF になってる – Windows7上で、IE9 でも Firefox12 でも Chrome19 でも同じ挙動 ※以上を Fiddler v.2.3.9.3 で確認。MacOSではどうなんでしょう?• クライアント側とサーバー側とで検証動作が異なる。 – ちなみに、XHR要求だと改行が LF で送信されたり。
  17. 17. 対応• サーバー側で CR+LF を LF に置換することで対応可能。• でも、漏れなく実装するのは大変では?• それでは jQuery Validation の実装を変更しましょう。 – オリジナルの $.validator.prototype.getLength(value, element ) が 呼び出される前に、value に含まれる改行文字(LF)を2文字に置換し てオリジナル実装に渡すよう、カスタムコードを ”差し込む”。
  18. 18. 実行時に Override 元の実装をorgに確保var org = $.validator.prototype.getLength; getLength メソッドを 独自実装に差し替え$.validator.prototype.getLength = function (value, element) { LFを適当な value = value.replace(/¥n/g, "++"); 2文字に置換 return org.apply(this, [value, element]); }; 元の実装をapplyで実行
  19. 19. Case 3. Cancel ボタン
  20. 20. Demo
  21. 21. 何が起きてる?• “cancel” CSSクラスを持つ input か button がクリックさ れると「入力検証しない」のフラグが立つ。• そしてそのフラグは解除されない。 this .find("input,button") .filter(".cancel") .click(function() { validator.cancelSubmit = true; });
  22. 22. 正攻法 – input で Cancel ボタンを実装しない• a 要素で。• Twitter Bootstrap など昨今の CSS ライブラリを使えば、a も input も、同じ外観に作れる。
  23. 23. どうしても、という場合...• 「検証しない」フラグをワンショット遅延でオフに復元。 $(".cancel").click(function () { var validator = $(this).closest("form").validate(); setTimeout(function () { validator.cancelSubmit = false; }, 0); });
  24. 24. Case 4. IE8
  25. 25. Demo
  26. 26. 何が起きてる?• $.validator.elements メソッドの内部に原因• IE8 だとなぜか、$($(“form”)[0].elements).filter(“:input”) の結果が、要素数 = 0個になっている – IE9 でも、ドキュメントモードが IE8 かそれ以前だと再現
  27. 27. 対応 – jQuery Validation を最新に• この問題を抱えているのは、実は ver.1.8.0.1 まで。• jQuery Validation を ver.1.8.1 以降に Upgrade で解決。 – ver.1.8.1 のパッケージは 2011年6月10日頃から出現している模様。 – それ以前に作成されたASP.NET MVC3 アプリは注意?
  28. 28. jQuery Validation を最新にできない場合は...• $.validator.elements の実装を実行時に Override。• .filter(“:input”) ではなく、.find(“input, select, textarea”) で要素を絞り込む。$.validator.prototype.elements = function () { ... return $([]) .add(this.currentForm.elements) .find("input, select, textarea") ...;};
  29. 29. Case 5. CSS Class 名が検証ルール名にかぶった
  30. 30. Demo
  31. 31. 何が起きてる?• ASP.NET としての入力検証機構とは無関係に、jQuery Validation による入力検証機構は活きている• そのひとつ、CSSクラス名による入力検証の発動 – email – required – date – number – ...
  32. 32. jQuery Validation 標準の検証ルールは潰せる• $.validator.classRuleSettings からCSSクラス名ルールを削除 delete $.validator.classRuleSettings.email;
  33. 33. 徒然に
  34. 34. 些細なことにこだわってばかりで、自分が器の小さい人間に思えてきました...だって、結局は、サーバー側検証が機能するんだし...
  35. 35. 結局、フィードバックは、Microsoft を含め、どこにもしていません。他の仕事とか優先してしまい...どなたか Microsoft Connect とかに投稿いただません?
  36. 36. Web Forms や、MVC2 までのクライアント側入力検証では、些細とはいえ、こんな問題はなかったよな... と思ったり。さすが Microsoft 純正品クォリティ?今振り返るに、jQuery Validation の採用はどうだったんだろう...
  37. 37. Thank you...
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×