nodejs - ilk argüman bir dize veya Buffer olmalıdır - http.request ile response.write kullanılırken


94

Sadece belirli bir URL'nin HTTP durumunu veren bir düğüm sunucusu oluşturmaya çalışıyorum.

Yanıtı res.write ile temizlemeye çalıştığımda, şu hatayı alıyorum: yeni TypeError atın ('ilk bağımsız değişken bir dizge veya Buffer olmalıdır');

Ancak bunları console.log ile değiştirirsem, her şey yolunda gider (ancak bunları konsola değil tarayıcıya yazmam gerekir).

Kod

var server = http.createServer(function (req, res) {
    res.writeHead(200, {"Content-Type": "text/plain"});

    request({
        uri: 'http://www.google.com',
        method: 'GET',
        maxRedirects:3
    }, function(error, response, body) {
        if (!error) {
            res.write(response.statusCode);
        } else {
            //response.end(error);
            res.write(error);
        }
    });     

    res.end();
});
server.listen(9999);

Bir yere geri arama eklemem gerektiğine inanıyorum ama oldukça kafam karıştı ve herhangi bir yardım için minnettarım.

Yanıtlar:


32

İstek bir geri arama yöntemini alır, eşzamansızdır! Bu yüzden, geri arama yürütüldüğünde res.end()çağrılan olabileceğini varsayıyorum . Geri arama içinde isteği kapatmayı deneyin.


1
Bunu yaptım ve ayrıca .toString eklendi. Çok teşekkürler.
umutm

Görünüşe göre unutmuşum. Sadece yaptım. Teşekkürler.
umutm

1
@umutm Daha iyi yazılmış ve ayrıntılı cevaplar var, muhtemelen bunlardan birini kabul etmelisiniz; bu soruya gelen herkese görünür kılıyor.
Gaurav Agarwal

52

response.statusCodebir sayıdır, örneğin response.statusCode === 200değil '200'. Hata mesajının dediği gibi, writebir stringveya Buffernesneyi bekler , bu yüzden onu dönüştürmelisiniz.

res.write(response.statusCode.toString());

Ayrıca geri arama yorumunuz konusunda da haklısınız. res.end();geri writearamanın içinde, aramalarınızın hemen altında olmalıdır .


Evet, hile yaptı. Bir nodejs acemi olarak bunu bilmiyordum ve çok teşekkürler.
umutm

48

Bu hata mesajını alıyorum ve seçeneklerden bahsediyor. Herkes

Aslen bunu aldım

request.post({
    url: apiServerBaseUrl + '/v1/verify',
    body: {
        email: req.user.email
    }
});

Ben şuna değiştirdim:

request.post({
    url: apiServerBaseUrl + '/v1/verify',
    body: JSON.stringify({
        email: req.user.email
    })
});

ve şimdi hata mesajı olmadan çalışıyor gibi görünüyor ... yine de hata gibi görünüyor.

Sanırım bunu yapmanın daha resmi yolu:

 request.post({
        url: apiServerBaseUrl + '/v1/verify',
        json: true,
        body: {
            email: req.user.email
        }
    });

4
Sorununuz farklı, body varsayılan olarak bir dizge veya Tampon olması bekleniyor. Ayrıca, seçeneklere json: true ekleyerek bunu değiştirebilirsiniz (json serileştirilebilir olacak şekilde). Örneğin: request.post ({url: apiServerBaseUrl + '/ v1 / doğrulayın', gövde: {email: req.user.email}, json: true})
Nuno Tomas

2
Sen kaçınmak için bu kullanabilirsiniz stringify javascript request.post({ url: apiServerBaseUrl + '/v1/verify', json: { email: req.user.email } }
bsorrentino

13

Belli ki dizge veya tampon olmayan bir şey göndermeye çalışıyorsunuz. :) Konsol ile çalışır, çünkü konsol her şeyi kabul eder. Basit örnek:

var obj = { test : "test" };
console.log( obj ); // works
res.write( obj ); // fails

Herhangi bir şeyi dizeye dönüştürmenin bir yolu, bunu yapmaktır:

res.write( "" + obj );

ne zaman bir şey göndermeye çalışsan. Diğer yol, .toString()yöntemi çağırmaktır :

res.write( obj.toString( ) );

Hala aradığınız şey olmayabileceğini unutmayın. Dizeleri / arabellekleri her zaman .writebu tür numaralar olmadan geçirmelisiniz.

Bir yan not olarak: Bunun requestasenkron bir işlem olduğunu varsayıyorum . Eğer durum buysa, o res.end();zaman herhangi bir yazıdan önce çağrılacaktır, yani herhangi bir yazma yine de başarısız olacaktır (çünkü bağlantı o noktada kapatılacaktır). Bu satırı işleyiciye taşıyın:

request({
    uri: 'http://www.google.com',
    method: 'GET',
    maxRedirects:3
}, function(error, response, body) {
    if (!error) {
        res.write(response.statusCode);
    } else {
        //response.end(error);
        res.write(error);
    }
    res.end( );
});

Cevap ve detaylı bilgi için çok teşekkür ederim. Ve evet, res.end'i işleyiciye taşıdım. @Loganfsmyth'i daha önce olduğu gibi kabul ettim. Tekrar Thx.
umutm

1

Yanıta bir JSON nesnesi yazmak istiyorsanız, başlık içerik türünü application / json olarak değiştirin

response.writeHead(200, {"Content-Type": "application/json"});
var d = new Date(parseURL.query.iso);
var postData = {
    "hour" : d.getHours(),
    "minute" : d.getMinutes(),
    "second" : d.getSeconds()
}
response.write(postData)
response.end();

1

Ve ajax (XMLhttpRequest) ile çalışırken başka bir olasılık daha vardır (XMLhttpRequest), bilgiyi istemci tarafına geri gönderirken res.end (responsetext) yerine res.send (responsetext) kullanmalısınız.


1

Soru çözülmüş olmasına rağmen, hatanın doğru anlamının açıklığa kavuşturulması için bilgi paylaşımı.

Hata, ilgili kesme işlevi için gereken parametrenin gerekli biçimde, yani dize veya Tampon

Çözüm, parametreyi string olarak değiştirmektir.

breakingFunction(JSON.stringify(offendingParameter), ... other params...);

veya tampon

breakingFunction(BSON.serialize(offendingParameter), ... other params...);

0

İlk argüman string veya Buffer türünden biri olmalıdır. Alınan tür nesnesi

 at write_

Gövde verilerini istek modülüne iletirken yukarıdaki hata gibi alıyordum.

JSON olan başka bir parametre geçtim: doğru ve çalışıyor.

var option={
url:"https://myfirstwebsite/v1/appdata",
json:true,
body:{name:'xyz',age:30},
headers://my credential
}
rp(option)
.then((res)=>{
res.send({response:res});})
.catch((error)=>{
res.send({response:error});})
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.