Düğüm veya Express kullanarak JSON'u döndürmenin uygun yolu


440

Yani, aşağıdaki JSON nesnesini almaya çalışabilirsiniz:

$ 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"
}
$

Düğüm veya ekspres kullanan bir sunucudan gelen yanıtta tam olarak aynı gövdeyi üretmenin bir yolu var mı? Açıkçası, üstbilgileri ayarlayabilir ve yanıtın içerik türünün "application / json" olacağını gösterebilir, ancak daha sonra nesneyi yazmak / göndermek için farklı yollar vardır. Yaygın olarak kullanıldığını gördüğüm, formun bir komutunu kullanmaktır:

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

Ancak, bunun "sorunlar "mış gibi tartışabileceği iki nokta vardır:

  • Bir dize gönderiyoruz.
  • Dahası, sonunda yeni bir çizgi karakteri yoktur.

Başka bir fikir, komutu kullanmaktır:

response.send(anObject);

Bu, yukarıdaki ilk örneğe benzer bir kıvrım çıktısına dayalı bir JSON nesnesi gönderiyor gibi görünüyor. Bununla birlikte, bir terminalde kıvrılma tekrar kullanıldığında, gövdenin sonunda yeni bir çizgi karakteri yoktur. Peki, sonunda düğüm veya düğüm / ekspres kullanarak sonuna eklenen yeni bir çizgi karakteri ile böyle bir şeyi nasıl yazabilirim?

Yanıtlar:


620

Bu yanıt da bir dizedir, yanıtı önceden onaylanmış olarak göndermek istiyorsanız, bazı garip nedenlerden dolayı, JSON.stringify(anObject, null, 3)

Content-TypeÜstbilgiyi de ayarlamanız önemlidir 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
// >  }

Neden bir satırsonu ile sonlandırmak istediğinizden tam olarak emin değilim, ama bunu JSON.stringify(...) + '\n'başarmak için bunu yapabilirsiniz.

ekspres

Ekspres , bunun yerine seçenekleri değiştirerek bunu yapabilirsiniz .

'json replacer' JSON replacer geri çağrısı, varsayılan olarak null

'json spaces' Biçimlendirme için JSON yanıt uzayları, varsayılan olarak geliştirme 2, üretim 0

Aslında 40 olarak ayarlanması önerilmez

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

O zaman sadece bazı jsonlarla cevap verebilirsin.

res.json({ a: 1 });

Bunu 'json spacesyapılandırmak için 'yapılandırmasını kullanır.


3
Zaman ayırdığınız için teşekkür ederim. Size karşı dürüst olmak gerekirse, benim için bir sorunum yok. Sadece bir kişi (farklı saat diliminde) kullanmak istediğim formattan şikayet etti çünkü bir get yapmak istedi ve bir nedenden dolayı nesnesimi düzgün bir şekilde okuyamadı. Stringify'ın güzel versiyonunu not ettiğiniz için teşekkürler. :)
MightyMouse

2
Bu birisi, elle herhangi bir okuma yapmaya çalışmak yerine JSON dizesini nesnelere ayrıştırmalı veya bir tarayıcı uzantısı kullanmalıdır .
bevacqua

2
@akshay Daha da iyisi, res.sendcontent-type gönderilen öğe bir nesne veya dizi ise otomatik olarak JSON olarak ayarlanır .
royhowie

3
Ben kullanmak anlamına düşünüyorum res.end()sizin içinde http(non-ekspres) Örneğin
Tobias Funke

2
@ TobiasFünke haklı bence. res.send()çalışmıyor. Bir hata ise lütfen düzeltin. res.end()düzgün çalışıyor. Teşekkürler btw.
Kaushal28

410

Express.js 3x'ten beri yanıt nesnesinin tüm başlıkları sizin için doğru ayarlayan ve yanıtı JSON biçiminde döndüren bir json () yöntemi vardır.

Misal:

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

Zaman ayırdığınız için teşekkür ederim. Ancak, sorum o zamanlar başlıklar hakkında değildi. Daha çok insanın kıvrım yoluyla söyleyebileceği sonuç hakkındaydı. Yine de teşekkürler.
MightyMouse

53
Tamam, ancak bu yöntem de düzgün biçimlendirilmiş JSON döndürür. Yanıtın bir parçasıdır. Böylece res.json () doğru başlıkları belirler ve sonra JSON.stringify () sizin için otomatik olarak yanıt verir.
JamieL

19

Bir json dosyası göndermeye çalışıyorsanız akışları kullanabilirsiniz

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

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

10
FS nedir, boru nedir, okunabilir nedir? Cevabınız daha çok gizem
Aakash Dave


6

Express kullanıyorsanız u kullanabilirsiniz:

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

ya da sadece bu

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

5

Sadece boru ve birçok işlemciden birini kullanarak öngörebilirsiniz. Uygulamanız her zaman mümkün olduğunca küçük bir yük ile yanıt vermelidir.

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

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


4

Bunun için bir yardımcı yapabilirsiniz: Uygulamanızın her yerinde kullanabilmeniz için bir yardımcı işlevi yapın

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

İşte tüm konuları almaya çalıştığım konu yolum

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

Aldığımız yanıt

{
"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

Varsayılan İçerik Türü'nü ayarlamak ve belirli API'ler için İçerik Türü'nü farklı şekilde ayarlamak için bir ara katman yazılımı kullanabilirsiniz. İşte bir örnek:

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

Sorunun başlık yarısı için res.typeburaya bir ses vereceğim :

res.type('json')

eşittir

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

Kaynak: ekspres dokümanlar :

İçerik Türü HTTP üstbilgisini, belirtilen tür için mime.lookup () tarafından belirlendiği şekilde MIME türüne ayarlar. Tür “/” karakterini içeriyorsa, İçerik Türü'nü türüne ayarlar.


1

Express'in eski sürümü app.use(express.json())veya bodyParser.json() bodyParser ara katman yazılımı hakkında daha fazla bilgi

Express'in en son sürümünde 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}`))

Canım, yanıtı istekle karıştırıyorsunuz. BodyParser ara katmanı isteği ayrıştırmak içindir, böylece istek req.bodygövdesi olarak gönderilen nesne olur.
Matthias Hryniszak
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.