読者です 読者をやめる 読者になる 読者になる

やったこと

webサービスを作るときに考えたことを垂れ流します

ajaxでjsonデータを送るとき連想配列が送信できないケース!

プログラミング

jquery ajaxjsonのデータを送信しようとしたのですが、データがサーバ側へ届きませんでした(サーバ側で受信すると空になってる)。

この原因ですが、送ろうとしているデータが「object型」ではなくて「array型(連想配列)」だったせいみたいです。

以下のように「連想配列(array型)」を「オブジェクト」に変換してあげたら、ちゃんとデータが送信できるようになりました。

//連想配列の値のままでは送信できない
var test_arr = new Array();
test_arr["aaa"] = 111;
test_arr["bbb"] = 222;
test_arr["ccc"] = 333;

//連想配列をobjectに変換
var test_obj = {};
for(key in test_arr){
  test_obj [key] = test_arr[key];
}

//objectの値を送信
$.ajax({
  url: "../hogege/api",
  type: "POST",
  cache: false,
  dataType: "json",
  data: {'test_obj': test_obj},
  dataType: 'json'
}).done(function(data, textStatus, jqXHR){
  //通信成功!
}).fail(function(jqXHR, textStatus, errorThrown){
  //通信失敗!
});

スタックオーバーフローにもこのことが書いてありますね。
javascript - Send associate array with jquery ajax - Stack Overflow

こういう問題、日本語で検索するとあんましヒットしないのはなんでなんでしょうかね・・。
英語で検索すると一発で出てくるのですが・・。

以上です。


※P.S.
コメント欄の質問にお答えします。

もし私がCakePHP3で受信処理を書くとしたら、下記のような感じになると思います。

クライアントが送信してきた「hogege」の値と「fugaga」の値を、サーバ側の「Hogegeコントローラ」の「recvアクション」にて受信する処理です。

無事受信したら、クライアントに「ok」という情報と「無事受信完了しました!」という情報を送り返します。

<?php
namespace App\Controller;

use App\Controller\AppController;
use Cake\ORM\TableRegistry;

class HogegeController extends AppController
{
    public function initialize()
    {
      $this->loadComponent('RequestHandler');
    }

    public function recv()
    {
      //通信がajaxかチェック
      if (!$this->request->is('ajax')) {
        throw new BadRequestException();
      }

      //受信パラメータが存在するかチェック
      if (empty($this->request->data['hogege']) || empty($this->request->data['fugaga'])){
        throw new BadRequestException();
      }

      //受信パラメータを格納
      $hogege = $this->request->data['hogege'];
      $fugaga = $this->request->data['fugaga'];

      //-----------なんらかの処理
      //
      //-----------なんらかの処理

      //結果を返却
      $result['status'] = "ok";
      $result['msg'] = "無事受信完了しました!";
      $this->set(compact('result'));
      $this->set('_serialize', ['result']);
    }
}