node 또는 Express를 사용하여 JSON을 반환하는 올바른 방법


440

따라서 다음 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을 다시 사용하는 경우 본문 끝에 줄 바꿈 문자가 없습니다. 그렇다면 실제로 노드 또는 노드 / 표현을 사용하여 끝에 줄 바꿈 문자를 추가하여 실제로 이와 같은 것을 작성할 수 있습니까?

답변:


620

응답이 문자열 인 경우, 응답을 미리 보내려면 어색한 이유로 다음과 같은 것을 사용할 수 있습니다 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' 달성하기 위해 .

표현하다

명시 적으로 대신 옵션변경하여 이를 수행 할 수 있습니다 .

'json replacer' JSON 대체 콜백, 기본적으로 null

'json spaces' 형식화를위한 JSON 응답 공간, 개발시 기본값은 2, 프로덕션시 0

실제로 40으로 설정하지 않는 것이 좋습니다

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

그런 다음 json으로 응답 할 수 있습니다.

res.json({ a: 1 });

'json spaces'구성을 사용하여 이를 확인합니다.


3
시간 내 주셔서 감사합니다. 솔직히 말해서, 나는 내 문제가 없습니다. 다른 시간대의 누군가가 가져 오기를 원했기 때문에 사용중인 형식에 대해 불평했으며 어떤 이유로 든 내 개체를 올바르게 읽을 수 없었습니다. stringify의 멋진 버전에 주목 해 주셔서 감사합니다. :)
MightyMouse

2
이 사람은 실제로 손으로 읽는 대신 JSON 문자열을 객체로 구문 분석하거나 브라우저 확장 프로그램을 사용해야합니다 .
bevacqua

2
@akshay 전송 된 항목이 객체 또는 배열 인 경우 res.send자동으로 content-typeJSON 으로 자동 설정 됩니다.
royhowie

3
나는 당신 res.end()이 당신의 http(익스프레스가 아닌) 예제 에서 사용하려고했다고 생각합니다
Tobias Fünke

2
@ TobiasFünke가 맞습니다. res.send()작동하지 않는다. 실수 인 경우 수정하십시오. res.end()제대로 작동하고 있습니다. 감사합니다.
Kaushal28

410

Express.js 3x부터 응답 객체에는 json () 메소드가있어 모든 헤더를 올바르게 설정하고 JSON 형식으로 응답을 반환합니다.

예:

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

시간 내 주셔서 감사합니다. 그러나 제 질문은 당시 헤더에 관한 것이 아닙니다. 컬을 통해 말할 수있는 결과에 관한 것이 었습니다. 어쨌든 다시 감사합니다.
MightyMouse

53
그러나이 방법은 올바른 형식의 JSON도 반환합니다. 응답의 일부입니다. 따라서 res.json ()은 올바른 헤더를 설정 한 다음 JSON.stringify ()가 자동으로 응답합니다.
JamieL

19

JSON 파일을 보내려고하면 스트림을 사용할 수 있습니다

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

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

10
fs는 무엇이고, 파이프는 무엇이고, 읽을 수있는 것은 무엇입니까? 당신의 대답은 더 신비입니다
Aakash 데이브

11

res.json()기능 은 대부분의 경우 충분해야합니다.

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

res.json()기능 변환 매개 변수는 사용하여 JSON에 전달 JSON.stringify()하고 세트 Content-Type헤더application/json; charset=utf-8클라이언트가 자동으로 응답을 구문 분석 알고 HTTP 있도록.


6

Express를 사용하는 경우 다음을 사용할 수 있습니다.

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

아니면 그냥

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

5

파이프와 여러 프로세서 중 하나를 사용하여 미리 확인할 수 있습니다. 앱은 항상 가능한 한 적은 부하로 응답해야합니다.

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

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


4

도우미를 만들 수 있습니다 : 응용 프로그램의 어느 곳에서나 사용할 수 있도록 도우미 기능 만들기

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
    }
      ]
}

3

미들웨어를 사용하여 기본 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>`);
})

2

질문의 머리글 절반을 위해 res.type여기에 소리를 지겠습니다 .

res.type('json')

에 해당

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

출처 : 표현 문서 :

지정된 유형에 대해 mime.lookup ()에 의해 판별 된대로 Content-Type HTTP 헤더를 MIME 유형으로 설정합니다. type에 "/"문자가 포함되어 있으면 Content-Type을 type으로 설정합니다.


1

이전 버전의 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}`))

친애하는, 당신은 요청과 응답을 혼동하고 있습니다. BodyParser 미들웨어는 요청을 구문 분석하기 위해 요청의 req.body본문으로 전송 된 오브젝트입니다.
Matthias Hryniszak
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.