关于node.js:使用node或Express返回JSON的正确方法

Proper way to return JSON using node or Express

因此,可以尝试获取以下JSON对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ 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"
}
$

有没有一种方法可以在使用节点或Express的服务器的响应中生成完全相同的主体?显然,可以设置头并指出响应的内容类型将是"application/json",但是有不同的方法来编写/发送对象。我所看到的一个常用的方法是使用以下形式的命令:

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

然而,这有两个点,一个是可以争论的,好像他们是"问题"一样:

  • 我们正在发送一个字符串。
  • 而且,在结尾没有新行字符。

另一个想法是使用命令:

1
response.send(anObject);

这似乎是基于curl的输出发送一个JSON对象,类似于上面的第一个示例。但是,当在终端上再次使用curl时,主体的末尾没有新行字符。那么,如何才能用node或node/express在末尾附加一个新行字符来写下这样的内容呢?


这个响应也是一个字符串,如果您想发送经过预处理的响应,出于一些尴尬的原因,您可以使用类似于JSON.stringify(anObject, null, 3)的东西。

重要的是您也要将Content-Type头文件设置为application/json

1
2
3
4
5
6
7
8
9
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}

美化:

1
2
3
4
5
6
7
8
9
10
11
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(...) + '
'
来实现这一点。

快车

在Express中,您可以通过更改选项来实现这一点。

'json replacer' JSON replacer callback, null by default

'json spaces' JSON response spaces for formatting, defaults to 2 in development, 0 in production

实际上不建议设置为40

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

然后您可以用一些JSON来响应。

1
res.json({ a: 1 });

它将使用'json spaces配置来美化它。


由于express.js 3x,response对象有一个json()方法,该方法为您正确设置所有头,并以json格式返回响应。

例子:

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


如果要发送JSON文件,可以使用流

1
2
3
4
5
6
var usersFilePath = path.join(__dirname, 'users.min.json');

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


你可以用管道和许多处理器中的一个来美化它。你的应用应该总是以尽可能小的负载响应。

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

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


您可以使用中间件设置默认的内容类型,并为特定的API设置不同的内容类型。下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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>`);
})

如果您使用的是Express,您可以使用它:

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

或者只是这个

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


旧版本的Express use app.use(express.json())bodyParser.json()了解更多关于BodyParser中间件的信息

在最新版本的Express上,我们可以简单地使用res.json()

1
2
3
4
5
6
7
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}`))