どうしても名前空間を汚染したい時のjquery拡張
jsonpとかフラッシュから関数呼びたい時とかグローバルな名前空間汚したい時ってありますよね?
他と名前ぶつからないようにするの大変ですよね?
(注意:jquery.ajaxでjsonp呼び出す時はjqueryが内部で同じような事をしています)
作り方
jquery.makeNS.jsとか適当に名前をつけて保存します。
/* (C) makoto@2ch.to */ if(typeof jQuery === 'function' && typeof jQuery.makeNS === 'undefined' ) jQuery.makeNS = function($_){ var $ = jQuery; var $default = { top : window, prefix : 'jQuery_', object : {} }; $_ = $.extend($default,typeof $_ === 'function' ? {object:$_} : $_); var $c = $.now(); var $ns = null; while( typeof $_['top'][ $ns = $_['prefix'] + $c ] !== 'undefined' ) $c++; $_['top'][$ns] = $_['object']; return $ns; };
準備
〜の中でjQueryと先ほど作ったjquery.makeNS.jsをロードします。<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.min.js"></script> <script type="text/javascript" src="./jquery.makeNS.js"></script>
使い方
//window[$ns]に空のオブジェクトがセットされます。 var $ns = $.makeNS(); //window[$ns]に関数がセットされます。 var $ns = $.makeNS(function($_){console.log($_)}); //引数topで渡したオブジェクトの$nsに引数object(関数でも定数でも良い)で渡したオブジェクトがセットされます。 var $ns = $.makeNS({ top : window, //TOPのオブジェクト(省略可能) prefix : 'jQuery_', //名前空間の先頭文字(省略可能) object : {}, //名前空間にセットするオブジェクト(省略可能) });
formに値を渡すjquery拡張
formに値入れるのにいちいち
$(':input[name=name1]').val('value1');
$(':input[name=name2]').val('value1');
:
…って書くのがめんどくさいのでまとめて渡す拡張
作り方
jquery.fillInForm.jsとか適当に名前をつけて保存します。
/* (C) makoto@2ch.to */ (function($){ $.fn.extend({ fillInForm : function($_){ var $self = this; if( typeof $_ === 'string' ){ if( typeof $.parse === 'undefined' ) throw 'please install jQuery parse plugin'; $_ = $.parse($_); } $.each($_,function($k,$v){ $(':input[name='+$k+']',$self).val($v); }); } }); })(jQuery)
準備
〜の中でjQueryと先ほど作ったjquery.fillInForm.jsをロードします。<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.min.js"></script> <script type="text/javascript" src="./jquery.fillInForm.js"></script> <!-- ↓なくても動きますがロードしてあるとテキストも渡せるようになります --> <script type="text/javascript" src="./jquery.parse.js"></script>
使い方
オブジェクトを渡すだけです。idではなくnameですのでご注意ください。
//基本的な使い方 $('form').fillInForm({ name1 :'value1', name2 : value2' });
jquery.parse.jsと連動します。
//jquery.parse.jsがロードしてあればqueryっぽい文字列が渡せます $('form').fillInForm('name1=value1&name2=value2'); //もちろんparseメソッドの返り値をそのまま渡してもOK var $query = $.parse(); $('form').fillInForm($query);
jQueryにquery parserを追加する拡張
query_string(location.search)をパースしてオブジェクトを返す拡張
作り方
jquery.parse.jsとか適当に名前を付けて保存します。
jquery pluginはjQuery.fn.extend(object)を利用するのが作法ですがjQuery.parse()みたいな呼び出し出来なくなるので強引に拡張しています。
※jquery pluginとしては非常にお行儀の悪い書き方ですので真似しないでください。
コメントによるとこの拡張方法で問題無いみたいです
if(typeof jQuery === 'function' && typeof jQuery.parse === 'undefined' ) jQuery.parse = function($_){ var i,$R = {}; $_ = arguments.length === 0 ? location.search : new String($_); if( (i = $_.indexOf('?')) != -1 ) $_ = $_.substring(i+1); if( (i = $_.indexOf('#')) != -1 ) $_ = $_.substring(0,i); jQuery.each( $_.split('&') ,function(){ var $_ = this.split('='); if( typeof $_[0] === 'undefined ' || $_[0] === '') return; var $k = decodeURIComponent($_[0]); var $v = $_.length === 1 ? true : decodeURIComponent($_[1]); if( $k.match(/(.+)\[\]$/) ){ $k = RegExp.$1; if( !jQuery.isArray($R[$k]) ) $R[$k] = []; $R[$k].push($v); }else{ $R[ $k ] = $v; } }); return $R; };
準備
〜の中でjQueryと先ほど作ったjquery.parse.jsをロードします。<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.min.js"></script> <script type="text/javascript" src="./jquery.parse.js"></script>
使い方
どちらもオブジェクトが返ります。
//引数が無い場合location.searchを解析します。 var $query = $.parse(); console.log($query); //文字列を渡すと渡した文字列を解析します。 var $query = $.parse('test.html?key1=value1&key2=value2_1&key2=value2_2&key3&key4=&key5[]=value5_1&key5[]=value5_2#hash'); console.log( $query ); console.log( 'key' in $query );//keyが存在するか調べる console.log( $query['key1'] === 'value1' );//右辺がそのまま値になる console.log( $query['key2'] === 'value2_2' );//同じ名前が2回存在する場合後からの値で上書きされる console.log( $query['key5'] );//ただしkeyが[]で終わる場合配列になる console.log( $query['key3'] === true );//=が無い場合trueになる console.log( $query['key4'] === '' );//=の右辺が無い場合空文字になる
某ニュースサイトに紹介してもらった
「やばいサーバ負荷耐えれるかな?」とか浮かれてたのですがamazonってやっぱすごいですね。
まったく落ちる/不安定になるとか無しに1ドル程度で処理できちゃいました。
せっかくなので今回の構成の詳細を書いて行きたいと思います。
DNSサーバ
value-domainを利用しています。
(時々ポカをしてる気がしますが)無料で利用できるし名前解決が遅いということも無くそこそこ安心して利用してます。
WEB(静的コンテンツ)サーバ
ドメイン名のbacketを作成するとCNAMEレコードを設定するだけで、そのまま独自ドメインの(静的コンテンツ)サーバに出来ます。
最近はディレクトリーインデックスやエラードキュメントも設定できるのでめちゃくちゃ便利です。
注意点は
CGIやサーバサイドインクルード(SSI)は利用できないし別のサービスと組み合わせないとSSLも利用できないのと
「アップロードするときにpublicにするのを忘れないように!」<これ大切
今回はHTML,CSS,JSは全部S3にお任せしました。
エラードキュメントで特定のHTMLを呼び出してHTMLからJSでAPIを叩くという仕組みにしてるのでほとんどのアクセスはS3が処理してます。
APIサーバ
CRUD(今回はUに該当する処理はありません)はEC2のmicro instanceを利用しました。
個人のサービスのほとんどを置いてるサーバですが大部分はS3においたHTMLとJSが面倒みてくれてるので
APIは最低限のチェックとS3の操作だけで済むので普段と負荷は変わりませんでした。
細かい話だと、完全に設計ミスで取得処理がJSだけでは出来ずphp呼び出してるのが気になってしょうがないので今後のアップデートで対応したいと思っています。
DBサーバ
S3でコンテンツと同じバケット使ってます。
今回はプライマリーキーのみなので、普通のサーバだとinodeがきになりますがS3使ってるとまったく気にしなくていいのでがんがんファイルアウトしてます。
二番煎じで作っちゃいました。一度だけアクセス可能なURLを生成するネットサービス
gigazine.netさんでOne Time SecretというWEBサービスを紹介していましたが
日本語を入力するとエラーになるみたいで、twitterを見ていると日本語対応しないかな〜?とささやかれてたので作っちゃいました。
技術的には
ブラウザサイドで、パスフレーズを使ってテキストを可逆暗号化(blowfish)し、パスフレーズは非可逆暗号化(MD5)し
サーバサイドには暗号化された情報しか渡ってこないので非常にセキュアです。(その為SSLも必要ない)
もちろん取り出し時も入力されたパスフレーズを非可逆暗号化(MD5)し
URLのキーとMD5が一致した場合のみ可逆暗号化されたデータを返すようになっており、複合はブラウザサイドで行っています。
もちろん漏えいしないに越したことはないですが、万が一データファイルが漏えいしても解読は非常に困難な仕組みになっています。
ただし、大部分をブラウザサイドで行っているのでJavaScriptは必須です。
インフラは…
・html,javascript等はAmazon S3に配置してバーチャルホスト設定
・アルプリケーション(保存と取り出し)はAmazon EC2(Apache+PHP)
・データファイルはAmazon S3に保存
と、AWSにべったりな構成になっています。
formをajaxで呼び出すjquery拡張
formに入力させてsubmitされたらajaxでphp呼び出して〜って良くある処理を簡略化する拡張
jQureryを拡張する。
jquery.ajaxFrom.jsとか適当に名前を付けて保存します。
/* (C) makoto@2ch.to */ if(jQuery) jQuery.fn.extend({ ajaxForm : function($_){ var $opt = {}; if( typeof $_ === 'function' ) $opt.success = $_; if( typeof $_ === 'object' ) $opt = $.extend($opt,$_); return $(this).submit(function(event){ event.preventDefault(); return jQuery.ajax($.extend({ url : jQuery(this).attr('action'), type : jQuery(this).attr('method'), data : jQuery(this).serialize(), dataType : jQuery(this).attr('data-type') || 'json', },$opt) ); }); } });
jqueryとjquery.ajaxForm.jsを呼び出す
jQueryの後にロードしないとダメ
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.min.js"></script> <script type="text/javascript" src="./ajaxForm.js"></script>
使い方は二通り
関数を渡す
submitが押されてajax通信がsuccessだった時の処理を関数で渡します。
var $opt = jQuery('#form').ajaxForm(function($_){ console.log($_); });
オブジェクトを渡す
jQuery.ajaxが受け付けるパラメータならなんでも書けます。
var $opt = { success:function($_){ console.log($_); }, error: function(){ //エラー処理 } }; jQuery(form).ajaxForm($opt);
その他
デフォルトだとactionの実行結果はjsonを期待しています。
htmlやtextが変える場合formにdata-typeエレメントを定義することで変更することができます。
<form action="login.php" method="post" data-type="html"> <input type="text" name="i"> <input type="password" name="p"> </form>