ChatGPT解决这个技术问题 Extra ChatGPT

使用节点或 Express 返回 JSON 的正确方法

因此,可以尝试获取以下 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 或 express 在服务器的响应中生成完全相同的主体?显然,可以设置标头并指示响应的内容类型将是“application/json”,但是写入/发送对象有不同的方法。我见过的常用命令是使用以下形式的命令:

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

但是,这有两点可以争论,就好像它们是“问题”一样:

我们正在发送一个字符串。

而且,最后没有换行符。

另一个想法是使用命令:

response.send(anObject);

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


C
Community

该响应也是一个字符串,如果您想发送经过美化的响应,出于某种尴尬的原因,您可以使用类似 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}

美化:

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' 来实现这一点。

表达

您可以通过 changing the options instead 快速完成此操作。

'json replacer' JSON 替换回调,默认为 null 'json spaces' 用于格式化的 JSON 响应空间,开发中默认为 2,生产中默认为 0

实际上不建议设置为 40

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

然后你可以用一些 json 来回应。

res.json({ a: 1 });

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


感谢您的时间。老实说,我没有问题。只是有人(在不同的时区)抱怨我使用的格式,因为他想做一个 get 并且由于某种原因他们无法正确读取我的对象。感谢您注意到 stringify 的好版本。 :)
这个人应该真正将 JSON 字符串解析为对象或 using a browser extension,而不是尝试手动进行任何读取。
@akshay 更好的是,如果发送的项目是对象或数组,res.send 会自动将 content-type 设置为 JSON。
我认为您的意思是在您的 http(非表达)示例中使用 res.end()
我认为@TobiasFünke 是对的。 res.send() 不工作。如有错误请指正。 res.end() 工作正常。谢谢你顺便说一句。
J
JamieL

由于 Express.js 3x 响应对象有一个 json() 方法,它为您正确设置所有标头并返回 JSON 格式的响应。

例子:

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

感谢您的时间。但是,当时我的问题并不是关于标题。更多的是关于通过 curl 可以看到的结果。无论如何再次感谢。
好的,但是此方法也返回格式正确的 JSON。这是响应的一部分。因此 res.json() 设置正确的标头,然后 JSON.stringify() 会自动为您提供响应。
J
Jonathin

如果你使用 Express,你可以使用这个:

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

或者只是这个

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

v
vkarpov15

对于大多数情况,res.json() function 应该足够了。

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

res.json() 函数使用 JSON.stringify()sets the Content-Type header 将您传递到 JSON 的参数转换为 application/json; charset=utf-8,以便 HTTP 客户端知道自动解析响应。


u
user2878850

如果您尝试发送 json 文件,您可以使用流

var fs = require('fs');

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

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

什么是fs,什么是管道,什么是可读的?你的答案更神秘
readable 是实现 node.js stdlinbs 流接口的东西,请参阅 nodejs.org/api/…
N
Nishant

您可以为此制作一个助手:制作一个助手函数,以便您可以在应用程序的任何地方使用它

function getStandardResponse(status,message,data){
    return {
        status: status,
        message : message,
        data : data
     }
}

这是我试图获取所有主题的主题路线

router.get('/', async (req, res) => {
    const topics = await Topic.find().sort('name');
    return res.json(getStandardResponse(true, "", topics));
});

我们得到的回应

{
"status": true,
"message": "",
"data": [
    {
        "description": "sqswqswqs",
        "timestamp": "2019-11-29T12:46:21.633Z",
        "_id": "5de1131d8f7be5395080f7b9",
        "name": "topics test xqxq",
        "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575031579309.jpg",
        "category_id": "5de0fe0b4f76c22ebce2b70a",
        "__v": 0
    },
    {
        "description": "sqswqswqs",
        "timestamp": "2019-11-29T12:50:35.627Z",
        "_id": "5de1141bc902041b58377218",
        "name": "topics test xqxq",
        "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575031835605.jpg",
        "category_id": "5de0fe0b4f76c22ebce2b70a",
        "__v": 0
    },
    {
        "description": " ",
        "timestamp": "2019-11-30T06:51:18.936Z",
        "_id": "5de211665c3f2c26c00fe64f",
        "name": "topics test xqxq",
        "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575096678917.jpg",
        "category_id": "5de0fe0b4f76c22ebce2b70a",
        "__v": 0
    },
    {
        "description": "null",
        "timestamp": "2019-11-30T06:51:41.060Z",
        "_id": "5de2117d5c3f2c26c00fe650",
        "name": "topics test xqxq",
        "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575096701051.jpg",
        "category_id": "5de0fe0b4f76c22ebce2b70a",
        "__v": 0
    },
    {
        "description": "swqdwqd wwwwdwq",
        "timestamp": "2019-11-30T07:05:22.398Z",
        "_id": "5de214b2964be62d78358f87",
        "name": "topics test xqxq",
        "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575097522372.jpg",
        "category_id": "5de0fe0b4f76c22ebce2b70a",
        "__v": 0
    },
    {
        "description": "swqdwqd wwwwdwq",
        "timestamp": "2019-11-30T07:36:48.894Z",
        "_id": "5de21c1006f2b81790276f6a",
        "name": "topics test xqxq",
        "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575099408870.jpg",
        "category_id": "5de0fe0b4f76c22ebce2b70a",
        "__v": 0
    }
      ]
}

为什么你在身体里有地位?这就是 HTTP 状态码的全部意义所在。另外,为什么您有一条空白消息?如果状态是错误的,那么只有消息。唯一的响应应该是对象数组。我到处都看到这种情况,人们使用“数据”:这是一场噩梦,因为您必须为它编写自定义 json 解析。您通常不能只使用 json 库。这种反模式没有任何好处。
@Yoker 这取决于你兄弟你想要什么作为回应,我的前端要求是,所以如果你想要其他格式,我会以这种格式发送它,你可以随意使用。我分享的代码只是为了解释我们如何使用助手在节点中发送 JSON 响应。
加一,我在 res.json() 之后需要一些代码,所以我使用 return res.json(foo) 来避免 Cannot set headers after they are sent to the client
M
MalcolmOcean

对于问题的标题部分,我要在这里向 res.type 大声疾呼:

res.type('json')

相当于

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

来源:express docs

将 Content-Type HTTP 标头设置为 mime.lookup() 为指定类型确定的 MIME 类型。如果 type 包含“/”字符,那么它将 Content-Type 设置为 type。


p
pawelzny

您可以使用管道和众多处理器之一来美化它。您的应用程序应始终以尽可能小的负载响应。

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

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


Y
Yuci

您可以使用中间件设置默认 Content-Type,并为特定 API 设置不同的 Content-Type。这是一个例子:

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>`);
})

A
Aung Zan Baw

旧版 Express 使用 app.use(express.json())bodyParser.json() read more about bodyParser middleware

在最新版本的 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}`))

亲爱的,您将响应与请求混淆了。 BodyParser 中间件用于解析请求,以便 req.body 是作为请求正文发送的对象。
A
ABHI SHEK

这是解决方案:

//Here, JSON object is doc  
const M={"First Name":doc.First_Name,
          "Last Name":doc.Last_Name,
          "Doctor's Email":doc.Email,
          "Doctors Picture Link":doc.Image};
   res.write(JSON.stringify(M,null,10)+"\n");
   res.end();

其他仅渲染对象的方法

console.log(doc);
res.json(doc);
//Here,M is referred from the above code it is contains doc Object
res.send(M);

我如何使用 Mongoose 获取对象:

//Here, Handles contains my MongoDB Schema.
const NN=Handles.findOne().lean().exec(function(err, doc) {
console.log(doc);
});