http://lagoscript.org/jquery/upload?locale=jaは、
jQuery.uploadは、AjaxスタイルでファイルをアップロードするためのjQueryプラグインです。
http://lagoscript.org/jquery/upload?locale=ja
と書かれているとおり、ファイルを画面遷移無しでアップロードできる便利なjQueryのプラグイン……なのですが。
本日、使っていると、コールバックされるテキスト(html)が壊れてしまっているケースがあったので、注意が必要です。
具体的には、テーブルの1行分を渡そうとして、
<tr>〜</tr>
の部分だけを返そうとすると、はまります。
能書きはいいから、解決方法を早く、というせっかちな人はこちらをどうぞ。
具体例
こちらのサンプルをお試しください。
選択する(アップロードする)ファイルは別になんでもよいです。ファイル名と型を拾っているだけですので。
POSTの応答として、TABLE要素をすべて返すテスト1の場合では問題なく表示されるのですが、TR要素しか返さないテスト2の場合は、そもそも戻ってきたhtmlの段階で、タグが消えてしまっています。
サンプルのソースコード
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Script-Type" content="text/javascript"> <title>jQuery.uploadの不具合?</title> <style> table, table th, table td { border: solid 1px navy; border-collapse: collapse; } pre { border: solid 1px purple; } </style> <script src="./jquery-1.7.1.min.js"></script> <script src="./jquery.upload-1.0.2.min.js"></script> <script> (function(w,d){ function escape_html(html){ var ehtml=html.replace(/&/g,'&').replace(/>/g,'>').replace(/</g,'<'); return ehtml; } $().ready(function(){ $('input[type=file]').change(function() { var jq_input=$(this), jq_form=jq_input.parent('form'), id_base=jq_form.attr('id'); jq_input.upload(jq_form.attr('action'), function(html) { $('#container1_'+id_base).append($(html)); $('#container2_'+id_base).val(html); $('#container3_'+id_base).html(escape_html(html)); }, 'html'); }); }) })(window, document); </script> </head> <body> <h1><a href="http://lagoscript.org/jquery/upload?locale=ja">jQuery.upload</a>の不具合?</h1> <div> <h2><a href="./table.php">テスト1 (<table>〜</table>)</a></h2> <form action="./table.php" method="POST" enctype="multipart/form-data" id="test1"> <input type="file" value="" id="upload_file" name="upload_file" /> </form> <h3>結果</h3> <div id="container1_test1"></div> <h4>HTML(TEXTAREA)</h4> <textarea id="container2_test1" rows="12" cols="80"></textarea> <h4>HTML(エスケープ後)</h4> <pre id="container3_test1"></pre> </div> <hr /> <div> <h2><a href="./tr.php">テスト2 (<tr>〜</tr>)</a></h2> <form action="./tr.php" method="POST" enctype="multipart/form-data" id="test2"> <input type="file" value="" id="upload_file" name="upload_file" /> </form> <h3>結果</h3> <table> <tbody id="container1_test2"> </tbody> </table> <h4>HTML(TEXTAREA)</h4> <textarea id="container2_test2" rows="12" cols="80"></textarea> <h4>HTML(エスケープ後)</h4> <pre id="container3_test2"></pre> </div> </body> </html>
jQuery.uploadの使い方としては、特に特殊なことはやっていないつもりです。
追記
余談ながら、
<tr>〜</tr>
だけを返すとはまる、ということであれば、サーバ側で
<table><tbody><tr>〜</tr></tbody></table>
とダミーの<table>…</table>でくくっておいて、クライアント側で$('<table>…</table>').find('tr:first')なりして取り出せばよい、という話もあります。
これなら、new FormData() をサポートしないブラウザでもなんとか。
追記その2
そういえば、TABLE要素っていろいろ特殊だったなぁ、と思い出してみたり。
過去に
【JavaScript】IE6におけるtable要素の初期化: 風柳亭
【JavaScript】IE6でTABLE要素内をHTMLで書換える関数: 風柳亭
こんな記事も書いていた。