jQueryをつかってGAEとJSONをやりとり
GWに突入したので、なんとかコードを書く時間を捻出していく!ぞ。
jQuery の Ajax を利用して、GAEにJSONデータを送り、GAE側で処理してJSONを送り返す検証。
送信画面側 jQuery 側での対応
ボタンを押下したタイミングで、POSTリクエストを送る。以下は、ボタン押下時のイベントハンドラ抜粋。
- dataType を ‘json’とする
- contentType を ‘application/json’ とする (通常のPOSTだと、application/x-www-form-urlencoded でJSON文字列として渡らない)
- data を JSON.stringify で文字列に変換する
$("#create_project").click(function(){ json_data = {name:'sample',data:'sample_data'}; $.ajax({ url: "/project", type: "POST", dataType: "json", contentType: "application/json; charset=utf-8", data: JSON.stringify(json_data), success: function(data){ // オブジェクトが返ってきたかを確認 alert(data.name); } });
受信側GAEでの対応
Project クラスの中だけが該当の処理。
- reuqest.body から、JSON 文字列を取得する(request.POST や request.params には格納されない)
- json.loads で JSON文字列から、辞書オブジェクトに変換(特定のクラスへの変換は今後確認する)
- GAE側で処理した証として、値を変更
- レスポンス側も、content-Type を application/json を指定する
- 辞書オブジェクトを、JSON文字列に変換して応答する
# -*- coding:utf-8 -*- import webapp2 from google.appengine.ext.webapp import template from google.appengine.api import users import os import json class Project(webapp2.RequestHandler): def post(self): # リクエストからJSONを取得する json_data = self.request.body # JSON をオブジェクトに obj = json.loads(json_data) obj['name'] = obj['name'] + " via server." # Content-Type は application/json self.response.content_type = 'application/json; charset=utf-8' # 文字列に変換して返す self.response.out.write(json.dumps(obj)) class MainPage(webapp2.RequestHandler): def get(self): user = users.get_current_user() if user: login_url = users.create_logout_url("/") login_title = 'Logout' user_nickname = user.nickname() else: login_url =users.create_login_url("/") login_title = 'Login' user_nickname = '' template_values = {'login_url':login_url, 'login_title':login_title, 'user_nickname':user_nickname } path = os.path.join(os.path.dirname(__file__),'templates/index.html') self.response.out.write(unicode(template.render(path, template_values))) application = webapp2.WSGIApplication([ ('/', MainPage), ('/project', Project), ], debug=True) def main(): application.run() if __name__ == "__main__": main()
ということで、とりあえず、想定通りには動いたよ。と。