it-swarm.com.ru

Правильный способ вернуть JSON с помощью узла или Express

Итак, можно попытаться получить следующий объект JSON:

$ curl -i -X GET http://echo.jsontest.com/key/value/anotherKey/anotherValue
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=ISO-8859-1
Date: Wed, 30 Oct 2013 22:19:10 GMT
Server: Google Frontend
Cache-Control: private
Alternate-Protocol: 80:quic,80:quic
Transfer-Encoding: chunked

{
   "anotherKey": "anotherValue",
   "key": "value"
}
$

Есть ли способ получить точно такое же тело в ответе от сервера, используя узел или экспресс? Ясно, что можно установить заголовки и указать, что тип содержимого ответа будет «application/json», но тогда есть разные способы записи/отправки объекта. То, что я часто видел, используется командой вида:

response.write(JSON.stringify(anObject));

Однако в этом есть два момента, в которых можно утверждать, что это были «проблемы»:

  • Мы отправляем строку.
  • Более того, в конце нет символа новой строки.

Другая идея заключается в использовании команды:

response.send(anObject);

Похоже, что это отправка JSON-объекта на основе вывода curl, как в первом примере выше. Тем не менее, нет символа новой строки в конце тела, когда curl снова используется на терминале. Итак, как же можно записать что-то вроде этого, добавив в конце символ новой строки, используя узел или узел/экспресс?

329
MightyMouse

Этот ответ также является строкой. Если вы хотите отправить ответ предварительно, по какой-то неловкой причине, вы можете использовать что-то вроде JSON.stringify(anObject, null, 3)

Важно также установить заголовок Content-Type в application/json.

var http = require('http');

var app = http.createServer(function(req,res){
    res.setHeader('Content-Type', 'application/json');
    res.end(JSON.stringify({ a: 1 }));
});
app.listen(3000);

// > {"a":1}

Prettified:

var http = require('http');

var app = http.createServer(function(req,res){
    res.setHeader('Content-Type', 'application/json');
    res.end(JSON.stringify({ a: 1 }, null, 3));
});
app.listen(3000);

// >  {
// >     "a": 1
// >  }

Я не совсем уверен, почему вы хотите завершить его с помощью новой строки, но вы можете просто сделать JSON.stringify(...) + '\n', чтобы добиться этого.

Экспресс

В экспрессе вы можете сделать это путем изменив параметры вместо .

'json replacer' обратный вызов заменителя JSON, по умолчанию null

'json spaces' пространства ответов JSON для форматирования, по умолчанию 2 в разработке, 0 в работе

На самом деле не рекомендуется устанавливать на 40

app.set('json spaces', 40);

Тогда вы можете просто ответить с JSON.

res.json({ a: 1 });

Он будет использовать конфигурацию 'json spaces для ее предварительного подтверждения.

484
bevacqua

Начиная с Express.js 3x, у объекта ответа есть метод json (), который правильно устанавливает все заголовки и возвращает ответ в формате JSON.

Пример:

res.json({"foo": "bar"});
329
JamieL

Если вы пытаетесь отправить файл JSON, вы можете использовать потоки

var usersFilePath = path.join(__dirname, 'users.min.json');

apiRouter.get('/users', function(req, res){
    var readable = fs.createReadStream(usersFilePath);
    readable.pipe(res);
});
17
Connor Leech

Вы можете просто настроить его, используя pipe и один из многих процессоров. Ваше приложение должно всегда отвечать с как можно меньшей нагрузкой.

$ curl -i -X GET http://echo.jsontest.com/key/value/anotherKey/anotherValue | underscore print

https://github.com/ddopson/underscore-cli

4
pawelzny

Вы можете использовать промежуточное программное обеспечение, чтобы установить тип контента по умолчанию и установить тип контента по-разному для определенных API. Вот пример:

const express = require('express');
const app = express();

const port = process.env.PORT || 3000;

const server = app.listen(port);

server.timeout = 1000 * 60 * 10; // 10 minutes

// Use middleware to set the default Content-Type
app.use(function (req, res, next) {
    res.header('Content-Type', 'application/json');
    next();
});

app.get('/api/endpoint1', (req, res) => {
    res.send(JSON.stringify({value: 1}));
})

app.get('/api/endpoint2', (req, res) => {
    // Set Content-Type differently for this particular API
    res.set({'Content-Type': 'application/xml'});
    res.send(`<note>
        <to>Tove</to>
        <from>Jani</from>
        <heading>Reminder</heading>
        <body>Don't forget me this weekend!</body>
        </note>`);
})
2
Yuci

если вы используете Express, вы можете использовать это:

res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({key:"value"}));

или только это

res.json({key:"value"});
0
IXOVER

Старые версии Express используют app.use(express.json()) или bodyParser.json()узнайте больше о промежуточном программном обеспечении bodyParser

В последней версии Express мы могли бы просто использовать res.json()

const express = require('express'),
    port = process.env.port || 3000,
    app = express()

app.get('/', (req, res) => res.json({key: "value"}))

app.listen(port, () => console.log(`Server start at ${port}`))
0
Aung Zan Baw