iT邦幫忙

0

jQuery $.post 傳入 json object

各位前輩好

我在前端使用 jQuery 的 $.post 去呼叫一個 API
這個 API 是用 Node.js Express 寫的

後端

app.post('/update', function (req, res) {
    console.log(req.body);
    console.log(req.body.list);
}

前端

$.post('/api/update', {
    list: [{
        ac: 'aa'
    }, {
        ac: 'bb'
    }]
});

前端丟出這個 post 的 ajax 後,我期望能接到Array,但在後端接到的是

Object {list[0][ac]: "aa", list[1][ac]: "bb"}

而像這樣的狀況,如果 list 的數量和值是動態變動的,我就不知道後端可以怎麼去接 list 的值了

而我用 POSTMAN (API測試程式) 去丟卻可以得到 Array

{
    list: [{
        ac: 'aa'
    }, {
        ac: 'bb'
    }]
}

Object {list: Array(2)}

想請問前輩是不是我 jQuery 的用法錯了?

2 個回答

1
Homura
iT邦研究生 3 級 ‧ 2018-07-03 17:54:29
最佳解答

postman這個工具可以產出code
在你send按鍵下面右邊有個code可以按
然後你選javascript->jquery AJAX
看看產出來的code裡面的Data到底長怎樣...

看更多先前的回應...收起先前的回應...
椅恩啾 iT邦新手 5 級 ‧ 2018-07-03 18:15:28 檢舉

感謝前輩指導

我照著操作後得到的字串是
{\r\n\t"list": [{\r\n\t\t"ac": "aa"\r\n\t}, {\r\n\t\t"ac": "bb"\r\n\t}]\r\n}
和問題內描述的不同處是在 Key 的地方沒有雙引號

這個會是問題點在嗎?

Homura iT邦研究生 3 級 ‧ 2018-07-03 19:35:47 檢舉

椅恩啾
你如果用裡面產生的程式碼執行
丟出來結果一樣Object {list: Array(2)}嗎?

椅恩啾 iT邦新手 5 級 ‧ 2018-07-04 09:38:12 檢舉

Homura大大

我拿 POSTMAN 產生的程式碼去跑,丟出來結果是
Object {list:"[{"ac":"aa"},{"ac":"bb"}]"}

看起來是 ajax 的問題 /images/emoticon/emoticon02.gif

Homura iT邦研究生 3 級 ‧ 2018-07-04 10:02:26 檢舉

椅恩啾
話說你是怎麼丟的啊?
是把json放在body的raw裡面嗎?
我怎麼丟都是展開的耶

椅恩啾 iT邦新手 5 級 ‧ 2018-07-04 11:31:24 檢舉

Homura大大

透過 POSTMAN 的話,我的確是把 json 放在 body 的 raw 裡面

透過POSTMAN 產生的 CODE 的話,我就直接把產生的 CODE 直接放到前端,用個按鈕去觸發

var settings = {
  "async": true,
  "crossDomain": true,
  "url": "http://127.0.0.1:3000/api/update",
  "method": "POST",
  "headers": {
    "Content-Type": "application/json",
    "Cache-Control": "no-cache",
    "Postman-Token": "a5ef27a8-3565-4d09-8e03-e7a3701db308"
  },
  "processData": false,
  "data": "{\r\n    \"list\": [{\r\n        \"ac\": \"aa\"\r\n    }, {\r\n        \"ac\": \"bb\"\r\n    }]\r\n}"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});

我也想要展開的 Array ... /images/emoticon/emoticon20.gif

Homura iT邦研究生 3 級 ‧ 2018-07-04 11:43:08 檢舉

椅恩啾
Object {list:"[{"ac":"aa"},{"ac":"bb"}]"}
Object {list: Array(2)}
應該是一樣的吧..
只是他顯示問題
應該沒關係吧...
然後你最初貼的那個
Object {list[0][ac]: "aa", list[1][ac]: "bb"}
這個好像才會有影響?

椅恩啾 iT邦新手 5 級 ‧ 2018-07-04 15:28:39 檢舉

Homura大大

Object {list:"[{"ac":"aa"},{"ac":"bb"}]"}

Object {list: Array(2)}

這兩個差別在於我在後端用 req.body.list[0]
前者得到undefined,需要用JSON.parse()才可以使用
後者得到{"ac":"aa"},可以直接用

最出貼的那個
Object {list[0][ac]: "aa", list[1][ac]: "bb"}
我完全不知道怎麼用 /images/emoticon/emoticon06.gif

Homura iT邦研究生 3 級 ‧ 2018-07-04 15:57:44 檢舉

椅恩啾
我突然了解你問題出在哪了
你postman丟出去的不是json啊
你list裡面變成一個字串了...
Object {list:"[{"ac":"aa"},{"ac":"bb"}]"}

你仔細看你的postman raw 右邊應該有丟出去的格式
把他從text改成json....
然後你應該會得到像下面這樣才是正確的
{ list: [ { ac: 'aa' }, { ac: 'bb' } ] }

椅恩啾 iT邦新手 5 級 ‧ 2018-07-04 18:38:34 檢舉

Homura大大

前端用 jQuery 做 ajax,後端得到
Object {list:"[{"ac":"aa"},{"ac":"bb"}]"}

我用 postman 直接 send 的話都可以得到
{ list: [ { ac: 'aa' }, { ac: 'bb' } ] }

我想問題應該是在於前端 ajax 沒辦法傳 array 這件事/images/emoticon/emoticon02.gif

我的 postman 選擇 raw 也有把 text 改成 application/json
所以 postman 都好好的/images/emoticon/emoticon07.gif

Homura iT邦研究生 3 級 ‧ 2018-07-04 19:44:25 檢舉

椅恩啾
我用ajax試了很正常
感覺是你node.js設定的問題...
我把我的code給你好了
你試試看
node.js

var BodyParser = require( 'body-parser' );
var Http = require( 'http' ),
    Router = require( 'router' ),
    server,
    router;
router = new Router();
 
server = Http.createServer( function( request, response ) {
  router( request, response, function( error ) {
    if ( !error ) {
      response.writeHead( 404 );
    } else {
      // Handle errors
      console.log( error.message, error.stack );
      response.writeHead( 400 );
    }
    response.writeHead( 200, {
        'Content-Type' : 'text/html'
        });
    response.end( `<!DOCTYPE html>
    <html>
        <head>
        </head>
        <body>
            <h1 id="aa">123</h1>
            <script src="https://code.jquery.com/jquery-3.3.1.js"
    integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
    crossorigin="anonymous"></script>
    </body>
    </html>` );
  });
});
 
server.listen( 3000, function() {
  console.log( 'Listening on port 3000' );
});

router.use( BodyParser() );
router.post('/update', function (req, res) {
    console.log(req.body);
    console.log(req.body.list[0]);
});

js

$.post('/update', {
"list": [{
"ac": "aa"
}, {
"ac": "bb"
}]
});
椅恩啾 iT邦新手 5 級 ‧ 2018-07-05 09:19:06 檢舉

Homura大大

真的耶,前輩你的 code 可以很正常的接到 Array
我試著將 express 的 code 整成一個 js 檔
我用 express 當後端都接不到 array
我會再試試看倒底是哪行出了問題

"use strict";

var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.set('json spaces', 4);

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: false
}));

// output nicely fomatted HTML
if (app.get('env') === 'development') {
  app.locals.pretty = true;
}

app.get('/', function(req, res) {
    res.end(`<!DOCTYPE html>
    <html>
        <head>
        </head>
        <body>
            <h1 id="aa">123</h1>
            <script src="https://code.jquery.com/jquery-3.3.1.js"
    integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
    crossorigin="anonymous"></script>
    </body>
    </html>`)
});

app.post('/update', function (req, res) {
  console.log(req.body);
  console.log(req.body.list[0]);
});

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function (err, req, res) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});


/**
 * Module dependencies.
 */

var debug = require('debug')('clubassist:server');
var http = require('http');

/**
 * Get port from environment and store in Express.
 */

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
 * Create HTTP server.
 */

var server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
 * Normalize a port into a number, string, or false.
 */

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 * Event listener for HTTP server "error" event.
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * Event listener for HTTP server "listening" event.
 */

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}
Homura iT邦研究生 3 級 ‧ 2018-07-05 09:27:00 檢舉

椅恩啾
你的app.use(bodyParser.json());
改成app.use(bodyParser());看看
我的Code是下面的寫法
不曉得有沒有關係

剛試著改了你的Code真的OK了...

椅恩啾 iT邦新手 5 級 ‧ 2018-07-06 09:49:45 檢舉

Homura大大

原來是 bodyParser 的問題嗎...
感謝協助小弟我抓問題
我會再去搜尋 bodyParser 跟 json 傳入值的相關問題

非常感謝!/images/emoticon/emoticon32.gif

0

物件資料傳遞會有些情況無法使用,
建議將array轉為json,後端再以json轉回array。

椅恩啾 iT邦新手 5 級 ‧ 2018-07-03 18:10:36 檢舉

感謝前輩建議,我會以這個方向先試試看

我要發表回答

立即登入回答