nodejs - อาร์กิวเมนต์แรกต้องเป็นสตริงหรือบัฟเฟอร์ - เมื่อใช้ response.write กับ http.request


94

ฉันแค่พยายามสร้างเซิร์ฟเวอร์โหนดที่แสดงสถานะ HTTP ของ URL ที่กำหนด

เมื่อฉันพยายามล้างการตอบกลับด้วย res.write ฉันได้รับข้อผิดพลาด: โยน TypeError ใหม่ ('อาร์กิวเมนต์แรกต้องเป็นสตริงหรือบัฟเฟอร์');

แต่ถ้าฉันแทนที่ด้วย console.log ทุกอย่างก็เรียบร้อยดี (แต่ฉันต้องเขียนลงในเบราว์เซอร์ไม่ใช่คอนโซล)

รหัสคือ

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

ฉันเชื่อว่าฉันควรเพิ่มการติดต่อกลับที่ไหนสักแห่ง แต่ค่อนข้างสับสนและขอความช่วยเหลือใด ๆ

คำตอบ:


32

คำขอใช้วิธีการโทรกลับแบบ async! ดังนั้นฉันจึงสมมติว่าเมื่อดำเนินการโทรกลับres.end()อาจถูกเรียก ลองปิดคำขอภายในการติดต่อกลับ


1
ทำเช่นนั้นและยังเพิ่ม. toString ขอบคุณมาก.
umutm

ดูเหมือนว่าฉันจะลืมไป เพิ่งทำมัน ขอบคุณ.
umutm

1
@umutm มีคำตอบที่เขียนดีและละเอียดกว่านี้คุณน่าจะยอมรับหนึ่งในนั้น ทำให้ทุกคนมองเห็นคำถามนี้
Gaurav Agarwal

52

response.statusCodeเป็นจำนวนเช่นไม่response.statusCode === 200 '200'ตามที่ระบุข้อความแสดงข้อผิดพลาดwriteคาดว่าเป็นstringหรือBufferวัตถุดังนั้นคุณต้องแปลง

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

คุณยังถูกต้องเกี่ยวกับความคิดเห็นในการติดต่อกลับของคุณด้วย res.end();ควรอยู่ในการติดต่อกลับด้านล่างการwriteโทรของคุณ


ใช่นั่นเป็นเคล็ดลับ ในฐานะมือใหม่ nodejs ไม่รู้เรื่องนั้นและขอบคุณมาก
umutm

48

ฉันได้รับข้อความแสดงข้อผิดพลาดนี้และกล่าวถึง options.body

ฉันมีสิ่งนี้เดิม

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

ฉันเปลี่ยนเป็นสิ่งนี้:

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

และดูเหมือนว่าจะใช้งานได้โดยไม่มีข้อความแสดงข้อผิดพลาด ... ดูเหมือนว่าจะมีข้อผิดพลาด

ฉันคิดว่านี่เป็นวิธีที่เป็นทางการมากกว่าที่จะทำ:

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

4
ปัญหาของคุณแตกต่างกันโดยค่าเริ่มต้นเนื้อหาคาดว่าจะเป็นสตริงหรือบัฟเฟอร์ คุณยังสามารถเปลี่ยนได้ (เพื่อให้เป็นอนุกรม json) โดยเพิ่ม json: true ให้กับตัวเลือก เช่น: request.post ({url: apiServerBaseUrl + '/ v1 / verification', body: {email: req.user.email}, json: true})
Nuno Tomas

2
คุณสามารถใช้สิ่งนี้เพื่อหลีกเลี่ยงการสตริง javascript request.post({ url: apiServerBaseUrl + '/v1/verify', json: { email: req.user.email } }
bsorrentino

13

เห็นได้ชัดว่าคุณกำลังพยายามส่งสิ่งที่ไม่ใช่สตริงหรือบัฟเฟอร์ :) ใช้งานได้กับคอนโซลเนื่องจากคอนโซลยอมรับทุกอย่าง ตัวอย่างง่ายๆ:

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

วิธีหนึ่งในการแปลงอะไรก็ได้เป็นสตริงก็คือ:

res.write( "" + obj );

เมื่อใดก็ตามที่คุณพยายามส่งบางสิ่ง อีกวิธีหนึ่งคือการเรียก.toString()method:

res.write( obj.toString( ) );

โปรดทราบว่าอาจยังไม่ใช่สิ่งที่คุณกำลังมองหา คุณควรส่งสตริง / บัฟเฟอร์ไป.writeโดยไม่มีเทคนิคดังกล่าว

หมายเหตุด้านข้าง: ฉันถือว่าrequestเป็นการดำเนินการแบบอะซิงโครนัส หากเป็นเช่นนั้นres.end();จะถูกเรียกก่อนการเขียนใด ๆ กล่าวคือการเขียนใด ๆ ก็จะล้มเหลวอยู่ดี (เนื่องจากการเชื่อมต่อจะถูกปิด ณ จุดนั้น) ย้ายบรรทัดนั้นไปยังตัวจัดการ:

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

ขอบคุณมากสำหรับคำตอบและข้อมูลโดยละเอียด และใช่ฉันได้ย้าย res แล้วส่งไปยังตัวจัดการ ฉันยอมรับ @loganfsmyth เหมือนเดิม ขอบคุณอีกครั้ง
umutm

1

หากคุณต้องการเขียนออบเจ็กต์ JSON ในการตอบสนองให้เปลี่ยนประเภทเนื้อหาส่วนหัวเป็น 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();

1

และมีความเป็นไปได้อื่น (ไม่ใช่ในกรณีนี้) เมื่อทำงานกับ ajax (XMLhttpRequest) ในขณะที่ส่งข้อมูลกลับไปยังไคลเอนต์คุณควรใช้res.send (responsetext)แทน res.end (responsetext)


1

แม้ว่าคำถามจะได้รับการแก้ไข แต่การแบ่งปันความรู้เพื่อชี้แจงความหมายที่ถูกต้องของข้อผิดพลาด

ข้อผิดพลาดบอกว่าพารามิเตอร์ที่จำเป็นสำหรับฟังก์ชันการทำลายที่เกี่ยวข้องไม่อยู่ในรูปแบบที่ต้องการเช่นสตริงหรือบัฟเฟอร์

วิธีแก้คือเปลี่ยนพารามิเตอร์เป็นสตริง

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

หรือบัฟเฟอร์

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

0

อาร์กิวเมนต์แรกต้องเป็นสตริงประเภทหนึ่งหรือบัฟเฟอร์ วัตถุชนิดที่ได้รับ

 at write_

ฉันได้รับข้อผิดพลาดข้างต้นขณะที่ฉันส่งข้อมูลร่างกายไปยังโมดูลคำขอ

ฉันได้ส่งผ่านพารามิเตอร์อื่นที่เป็น JSON: จริงและใช้งานได้

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});})
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.