nodejs - argumen pertama harus berupa string atau Buffer - saat menggunakan response.write dengan http.request

93

Saya hanya mencoba membuat server node yang menampilkan status HTTP dari URL tertentu.

Ketika saya mencoba untuk menghilangkan respon dengan res.write, saya mendapatkan error: throw new TypeError ('argumen pertama harus berupa string atau Buffer');

Tetapi jika saya menggantinya dengan console.log, semuanya baik-baik saja (tapi saya perlu menuliskannya ke browser, bukan konsol).

Kodenya adalah

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

Saya yakin saya harus menambahkan panggilan balik di suatu tempat tetapi cukup bingung dan bantuan apa pun dihargai.

umutm
sumber

Jawaban:

32

Permintaan mengambil metode panggilan balik, asinkronnya! Jadi saya berasumsi, pada saat callback dijalankan, res.end()mungkin dipanggil. Coba tutup permintaan dalam panggilan balik.

Gaurav Agarwal
sumber
1
Melakukan itu dan juga menambahkan .toString. Terimakasih banyak.
umutm
Sepertinya saya lupa. Lakukan saja. Terima kasih.
umutm
1
@umutm Ada lebih banyak jawaban yang ditulis dengan baik dan terperinci, Anda mungkin harus menerima salah satunya; membuatnya terlihat oleh siapa pun yang datang ke pertanyaan ini.
Gaurav Agarwal
52

response.statusCodeadalah angka, mis. response.statusCode === 200, bukan '200'. Seperti pesan kesalahan mengatakan, writemengharapkan stringatau Bufferobjek, jadi Anda harus mengubahnya.

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

Anda juga benar tentang komentar panggilan balik Anda. res.end();harus berada di dalam panggilan balik, tepat di bawah writepanggilan Anda .

loganfsmyth
sumber
Ya, itu berhasil. Sebagai seorang pemula nodejs, tidak tahu itu dan terima kasih banyak.
umutm
48

Saya mendapatkan pesan kesalahan ini dan menyebutkan options.body

Saya memiliki ini awalnya

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

Saya mengubahnya menjadi ini:

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

dan tampaknya berfungsi sekarang tanpa pesan kesalahan ... tampaknya seperti bug.

Saya pikir ini adalah cara yang lebih resmi untuk melakukannya:

 request.post({
        url: apiServerBaseUrl + '/v1/verify',
        json: true,
        body: {
            email: req.user.email
        }
    });
Alexander Mills
sumber
4
Masalah Anda berbeda, body diharapkan secara default berupa string atau Buffer. Anda juga dapat mengubahnya (menjadi json serializable) menambahkan json: true ke opsi. Misalnya: request.post ({url: apiServerBaseUrl + '/ v1 / verifikasi', body: {email: req.user.email}, json: true})
Nuno Tomas
2
Anda dapat menggunakan ini untuk menghindari stringify javascript request.post({ url: apiServerBaseUrl + '/v1/verify', json: { email: req.user.email } }
bsorrentino
13

Nah, jelas Anda mencoba mengirim sesuatu yang bukan string atau buffer. :) Ia bekerja dengan konsol, karena konsol menerima apa saja. Contoh sederhana:

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

Salah satu cara untuk mengubah apa pun menjadi string adalah dengan melakukan itu:

res.write( "" + obj );

kapan pun Anda mencoba mengirim sesuatu. Cara lain adalah dengan memanggil .toString()metode:

res.write( obj.toString( ) );

Perhatikan bahwa itu mungkin masih bukan yang Anda cari. Anda harus selalu meneruskan string / buffer ke .writetanpa trik seperti itu.

Sebagai catatan tambahan: Saya berasumsi bahwa itu requestadalah operasi yang tidak sinkron. Jika demikian, maka res.end();akan dipanggil sebelum tulisan apapun, yaitu tulisan apapun akan tetap gagal (karena koneksi akan ditutup pada saat itu). Pindahkan baris itu ke dalam pawang:

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( );
});
aneh
sumber
Terima kasih banyak atas jawaban dan info detailnya. Dan, ya, saya telah memindahkan hasil akhir ke pawang. Saya telah menerima @loganfsmyth seperti sebelumnya. Terima kasih lagi.
umutm
1

jika Anda ingin menulis objek JSON ke respons, ubah jenis konten header ke application / json

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();
Mohsin Muzawar
sumber
1

Dan ada kemungkinan lain (tidak dalam kasus ini) ketika bekerja dengan ajax (XMLhttpRequest), saat mengirim informasi kembali ke klien, Anda harus menggunakan res.send (responsetext) daripada res.end (responsetext)

Prajith P.
sumber
1

Meskipun pertanyaannya terpecahkan, berbagi pengetahuan untuk klarifikasi tentang arti yang benar dari kesalahan tersebut.

Kesalahan mengatakan bahwa parameter yang diperlukan untuk fungsi pemutusan yang bersangkutan tidak dalam format yang diperlukan yaitu string atau Buffer

Solusinya adalah mengubah parameter menjadi string

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

atau penyangga

breakingFunction(BSON.serialize(offendingParameter), ... other params...);
Zameer Ansari
sumber
0

Argumen pertama harus salah satu dari jenis string atau Buffer. Objek tipe yang diterima

 at write_

Saya mendapatkan kesalahan seperti di atas saat mengirimkan data tubuh ke modul permintaan.

Saya telah melewati parameter lain yaitu JSON: true dan kerjanya.

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});})
A. PRABIN SARAB
sumber