fc2ブログ

JSONを使ってAjaxでデータ受信してみる

Ajaxでのデータ受信はXMLしか知らなかった。
JSONも覚えた方がいいよなと思い立ち、やり方を調べて使ってみた。

結論から言えば、JSONはXMLに比べるとかなり楽。覚えるのもプログラミングも。
JavaScriptで使用するデータを渡す場合はJSONの方がいいな。
XMLパースエラーを気にせずに、< > & をそのまま送れるのもいい。" は \ でエスケープする必要があるが。

去年私用で作ったプログラムを、JSONを使うように変更した。
変更前のDjangoテンプレート
msg は処理結果メッセージ文字列で、outdataLがデータ配列
  <?xml version='1.0' encoding='UTF-8'?>
  <doc>
    <msg>{{ msg }}</msg>
    {% if outdataL %}
      {% for outdata in outdataL %} <data>{{ outdata }}</data>
      {% endfor %}
    {% endif %}
  </doc>

JSON用に変更したDjangoテンプレート
  {"msg" : "{{msg}}"
    {% if outdataL %}
      ,
      "dataL" : [
      {% for outdata in outdataL %} "{{ outdata }}"
        {% if not forloop.last %},{% endif %}
      {% endfor %}
      ]
    {% endif %}
  }
配列の最後にコンマを付加しないよう、forloop.last で判定した。

HTTPヘッダのContent-TypeもJSON用に変更。
  self.response.headers['Content-Type'] = ('text/javascript; '
      'charset=utf-8')
サーバー側の変更はこのぐらい。他にもXMLパースに関する部分を少々変更したが略。

JavaScriptの、JSONを使ってAjaxでデータ受信する部分は以下のようになった。jQueryはver1.4.4を使用。
  $.ajax({
    url: acturl, // 実行されるURL
    type: 'GET',
    dataType: 'json',
    timeout: 20000, // タイムアウト時間(ミリ秒)
    beforeSend: function() { // 送信前に実行される処理
      $sbtn.css('display','none'); // 送信ボタン非表示
      $msgdiv.text('データ送信中'); // 送信メッセージ表示
    },
    success: function(getdata) { // 通信成功時に実行される処理
      var outhtml = getdata.msg + '<br>';
      var dataArr = getdata.dataL;
      for (var i = 0; i < dataArr.length; i++) {
        /* 受信データ処理部分は略 */
      }
      $datadiv.html(outhtml); // 受信データ表示
      $sbtn.css('display','inline'); // 送信ボタン表示
      $msgdiv.remove(); // 送信メッセージ削除
    },
    error: function(XMLHttpRequest, status) { // 通信エラー時に実行される処理
      $sbtn.css('display','inline'); // 送信ボタン表示
      $datadiv.text(status); // エラーステータス表示
      $msgdiv.remove(); // 送信メッセージ削除
    }
  });
受け取ったデータを、そのままオブジェクトとして利用できるから楽だ。

ハマることも無く、すぐにJSONを使うことができた。
Ajaxの勉強は、XMLより先にJSONを使った方がいいんじゃないかと思った。
スポンサーサイト



jQuery + Ajax で何か作ろうとして、3日目にしてやっとできた

昨日の続き。
今日もいろいろとハマった。

・XMLHttpRequest.responseTextでレスポンスを取得できない。
ネットで調べたら、「文字コードがわからないからXMLを解析できない」とのこと。
header("Content-Type: text/plain; charset=UTF-8") を指定すればうまくいくとあったが、指定してもレスポンスヘッダが変わらない。
@PAGESを使ってPHPを動かしているのだが、ここが広告を載せるためにヘッダを上書きしているみたいだ。
フレームを使うユーザーのため menu.php には広告を表示しないとあったので、ファイル名を menu.php にしたところ、きちんとヘッダを設定できた。

・XMLHttpRequestオブジェクトを得できない場合がある。
jQuery.post()がXMLHttpRequestオブジェクトを返すので、それを使って処理していたのだが、サーバからのレスポンスが返ってくる前に後続処理が行われてしまう。
きちんとjQuery.post()の引数にcallback関数として渡すようにした。
あと、今まで見ていたjQueryリファレンスサイトがちょっと古いバージョンみたいで、ちゃんとver1.4.2のリファレンスを載せているサイトを見るようにした。

・レスポンスXML中の & が &amp; に変換される
DOMDocumentがやってる処理みたいなので、
DOMDocument->saveXML() が吐き出した文字列をhtmlspecialchars_decode()してからレスポンスするようにした。

・IEでレスポンス内の値を取得できない
DOMの使い方が悪かった。.item(0)とせずに、直接[0]を記述して配列要素を見てたり。
IEでは.textContentが使えないので、以下のような関数を作った。
// DOMの要素からテキストを取得
getTextfDom: function(elm){
  if(elm.textContent){
    return elm.textContent;
  }else{
    return elm.text;
  }
}
うちはIE8なんだけど、開発者ツールの存在を今日初めて知った。デフォルトでこれがついてるのはすごい。

そんなわけで、3日かけてやっと「Ajaxでデータ送受信」ができるようになった。
PHP, jQuery, XML が絡みあうので、原因を突き止めるのに時間がかかる。
@PAGESやブラウザといった実行環境の問題もある。
でもやっと「きちんと動くお手本」ができたので、原因の切り分けはやり易くなったかな。
さて明日から何をやろう。

jQuery + Ajax で何か作ろうとしたが・・・(2日目)

昨日の続き。
AjaxからのリクエストへのレスポンスXMLに、@PAGESが余計なヘッダフッタをつける問題。
  XMLHttpRequest.responseText でいったん文字列にして、正規表現でmatch()してXML部分のみ抽出
で解決。改行が入ってても大丈夫。

次はXMLから値の抽出。
文字列をパースしてXMLDocumentオブジェクトにする方法がわからなかったが、ネットで調べたコードをそのままパクる。
しかし、getElementByIdで目当ての要素をゲットできない。
ちょっと調べたところ、
「getElementByIdはDOM-HTML拡張で、指定したIDのHTML要素を参照する。」
とのこと。
HTMLっぽく見せれば取れるのかもしれないが、てきとうなタグ名つけてgetElementsByTagNameで取るように修正。

Ajaxでデータのやりとりができるようになったが、データを全角文字にしたところ問題発生。
XMLHttpRequest.responseTextでレスポンスを取得できない。
URIエンコードをしてみたが、取得できたりできなかったりする。文字コードに関係がありそうだ。
ResponseHeaderかなぁ。
ってところで今日も時間切れ。
今日書いたコードは実質20行ぐらいだが、所要時間は4時間。

jQuery + Ajax で何か作ろうとしたが・・・

Ajaxで何か作ってみようと、7月6日に作った物をAjaxを使うように修正しようとした。

まず、JavaScript側の実装。ボタンにクリックイベントをbindして、jQuery.post()し、responseを表示するだけ。
それだけなのだが、postするデータを作るところでハマった。
パラメータ=データ&パラメータ=データ
でいいみたいだが、CGIもやったことが無いので、いちいち調べた。

次に、PHP側の実装。XML DOMの作り方を調べた。DomDocumentクラスを使って作ることにしたが、初めてなのでいろいろとつまずく。子要素を追加したあとで、属性追加する方法に悩んだり。DomDocumentクラスのメソッドを調べてたが、属性追加はDOMElementクラスのメソッドを使うことがわかるまで時間がかかった。

JavaScriptは実質5行、PHPは実質8行なのに、たったこれだけ書くのに2時間ぐらいかかった。

そしてテスト。
とりあえず動かしてみようとやってみる。
javascript側でエラー発生だが、jQueryを使っているのでちょっと面倒だった。
bind時に指定するfunctionに()がついてたのを突き止めるまで時間がかかった。
onload時にfunctionが実行されている時点ですぐわかりそうだが、わからなかった。
PHPからのresponseをどうやってチェックしようかと思ったが、Firebugではコンソールにリクエストとレスポンスの内容が表示されていた。すごいぞFirebug。
データをPOSTしてPHPで作成されたXMLがちゃんと返ってくるところまではできたが、@PAGESが余計なヘッダフッダを付けてくる。
これじゃXMLとして処理できないなぁ。ってところで今日は時間切れ。コーディングとテストで所要時間計3時間。

<追記>
翌日もレスポンスの取得などに四苦八苦
3日目にしてやっとレスポンスをまともに取得できた。詳細はこちら
jQuery + Ajax で何か作ろうとしたが・・・(2日目)
jQuery + Ajax で何か作ろうとして、3日目にしてやっとできた

Ajaxの勉強をした

Ajaxの入門サイトを読んだ。
「Ajaxとは、JavaScriptのXMLHttpRequestオブジェクトを使って非同期通信をすることである」
の1行で説明できる。
XMLHttpRequestオブジェクトがわかれば、Ajaxのほとんどがわかると思う。
実際はサーバーサイドもXMLでデータを返すなど考慮する部分があるけど、クライアント側がメインの気がする。

思ってたよりも簡単そうなので、何か作ってみようかと思ったが、そういえばXMLがわからない。
XMLの入門サイトも読んでみる。
DTDとか考えなければ、XML形式で書くのも難しく無さそうだ。

XMLドキュメントもHTMLと同じようにJavaScript DOMを使って処理をすればいいのだろうか。
とにかく実際に作ってみればわかるだろうと思ったが、残念ながら時間が無くなった。
今日の勉強時間は3時間。AjaxとXMLの入門サイトを見て終わった。
趣味にかける時間を減らせばもっと勉強時間を取れるのだが、ダラダラと時間を潰してしまう。
プロフィール

himax64

Author: 南西
30代後半の無職です。
就活もせずダラダラ生きてます。
作ったもの

最新記事
人気記事
検索フォーム
カテゴリ
月別アーカイブ
最新コメント
最新トラックバック
RSSリンクの表示
QRコード
QRコード
カウンター