Backbone.jsでAPIに渡すときのメモ。
Backbone.sync とは
Backbone.sync とはBackboneがモデルからデータを取得したり保存したりする際に使う関数。
デフォルトでは、jQUery.ajaxを使ってRESTful JSON リクエストを送信し、jqXHRを受け取る。
また、オーバーライドも可能。
—————————-
RESTful とは
ウェブサービスのひとつの形
・明示的に HTTP メソッドを使う
・ステートレスにする
・ディレクトリー構造に似た URI を公開する
・XML、JSON (JavaScript Object Notation) のいずれか、またはその両方を転送する
jqXHR とは
XMLHttpRequestオブジェクトを一般化し、クロスブラウザ対応を行ったjQuery独自のオブジェクト。
—————————-
sync()の基本形
sync(method, model, [options])
method – the CRUD method ("create", "read", "update", or "delete")
model – the model to be saved (or collection to be read)
options – success and error callbacks, and all other jQuery request options
そしてmethodの部分は、
create → POST
read → GET
update → PUT
delete → DELETE
これらが入る。
そして今回のようにbackboneで得たデータを、APIで保存するために送る時には、
Backbone.Model.save()
を使うとよい。
save()の中で.sync()に渡り、APIとの通信が行われる。
試しにこの様なコードを書いて、みたところ、
Model.url = '/apipath/'; var data = {'name':'hoge'}; Model.set(data); Model.save(null, { success:function(){ console.log('success.') }, error:function(){ console.log('error....'); } })
apiの方で$_POSTが空な事に気づく。
Developer toolでNetworkを見ても、Request MethodはPOSTだし、Request Payloadに値も入っている。
ググって見ると、この記事に辿り着いた。
http://shusatoo.net/programming/php/backbone-model-save-postdata-read-php/
こちらにより、$_POST ではapplication/jsonのPOSTが取得出来ないという事を知る。
通常、phpでフォームのPOSTを受け取る時には、Content-Type: application/x-www-form-urlencoded という形式が想定されているので、$_POSTでの受け取りが可能になっている。
Backboneでは、上述のようにjsonリクエストを送信するため$_POSTでは受け取れないのだと思われる。
そこで、解決策はというと、
1."php://input"から、リクエストボディを直接受け取る。
2.Backnone.emulateJSON = trueに設定する。
の2通りがあるそうだ。
1."php://input" とは
読み込み専用のストリームで、 リクエストの body 部から生のデータを読み込むことができます。 POST リクエストの場合は $HTTP_RAW_POST_DATA よりも php://input を使うのが望ましいでしょう。php.ini ディレクティブの設定に依存しないからです。
参考: http://php.net/manual/ja/wrappers.php.php
2.Backnone.emulateJSON とは
If you're working with a legacy web server that can't handle requests encoded as application/json, setting Backbone.emulateJSON = true; will cause the JSON to be serialized under a model parameter, and the request to be made with a application/x-www-form-urlencoded MIME type, as if from an HTML form.
意訳:
もしapplication/jsonでエンコードされたデータを扱えないようなレガシー・ウェブサーバーであるなら、Backbone.emulateJSON = trueにセットすべきだ。 そうすればJSONはシリアライズされてリクエストはHTMLフォームのような、application/x-www-form-urlencoded MIME 形式で渡される。
どちらでも良さそうだが、今回はファイルアップロードなんかもないのでapplication/x-www-form-urlencodedで渡す必要はない。記事にならい、php://inputの方法を使う。
この場合、受け取るAPIでは、
$postedData = json_decode(file_get_contents('php://input'), TRUE);
のように受け取れば、正しく渡る。
また一つ疑問が解消された。ありがとうございます!