Правильный способ возврата JSON с помощью node или 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"
}
$

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

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

Однако это имеет две точки, где можно было бы утверждать, что они были "проблемами":

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

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

response.send(anObject);

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

Ответ 1

Этот ответ также является строкой. Если вы хотите отправить ответ предварительно, по какой-то неловкой причине, вы можете использовать что-то вроде 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 'для его предварительного подтверждения.

Ответ 2

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

Пример:

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

Ответ 3

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

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

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

Ответ 4

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

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

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

Ответ 5

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

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

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

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

Ответ 6

Вы можете использовать промежуточное программное обеспечение для установки стандартного Content-Type и устанавливать Content-Type по-разному для определенных 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>');
})

Ответ 7

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

В последней версии выражения мы могли бы просто использовать 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}'))

Ответ 8

Для заголовка половины вопроса я хочу дать здесь res.type:

res.type('json')

эквивалентно

res.setHeader('Content-Type', 'application/json')

Источник: экспресс-документы:

Устанавливает HTTP-заголовок Content-Type для типа MIME, как определено mime.lookup() для указанного типа. Если тип содержит символ '/', то он устанавливает тип контента для типа.

Ответ 9

Функция res.json() должна быть достаточной для большинства случаев.

app.get('/', (req, res) => res.json({ answer: 42 }));

Функция res.json() преобразует передаваемый вами параметр в JSON с помощью JSON.stringify(), а устанавливает заголовок Content-Type в application/json; charset=utf-8, чтобы клиенты HTTP знали, что они автоматически анализируют ответ.