2013-02-12 26 views
44

Tôi chỉ đang cố gắng tạo một máy chủ nút kết xuất trạng thái HTTP của một URL nhất định.nodejs - đối số đầu tiên phải là một chuỗi hoặc Bộ đệm - khi sử dụng response.write với http.request

Khi tôi cố gắng xóa bỏ phản hồi bằng res.write, tôi nhận được lỗi: ném TypeError mới ('đối số đầu tiên phải là chuỗi hoặc Bộ đệm');

Nhưng nếu tôi thay thế chúng bằng console.log, mọi thứ đều ổn (nhưng tôi cần viết chúng lên trình duyệt chứ không phải bàn điều khiển).

Mã này là

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

Tôi tin rằng tôi nên thêm một callback ở đâu đó nhưng khá bối rối và bất kỳ sự giúp đỡ được đánh giá cao.

Trả lời

8

Yêu cầu nhận một phương thức gọi lại, không đồng bộ! Vì vậy, tôi giả sử, vào thời điểm gọi lại được thực thi, res.end() có thể được gọi. Thử đóng yêu cầu trong cuộc gọi lại ?!

+1

Đã làm điều đó và cũng đã thêm .toString. Cảm ơn nhiều. – umutm

+0

@umutm tại sao không phải là một upvote? –

+0

Có vẻ như tôi đã quên. Chỉ cần làm điều đó. Cám ơn. – umutm

40

response.statusCode là một số, ví dụ: response.statusCode === 200, không phải '200'. Khi thông báo lỗi cho biết, write mong đợi đối tượng string hoặc Buffer, vì vậy bạn phải chuyển đổi nó.

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

Bạn cũng đúng về nhận xét gọi lại của mình. res.end(); phải nằm trong cuộc gọi lại, ngay bên dưới các cuộc gọi write của bạn.

+0

Vâng, đó đã làm các trick. Là một newbie nodejs, không biết điều đó và cảm ơn rất nhiều. – umutm

12

Vâng, rõ ràng là bạn đang cố gửi một thứ không phải là chuỗi hoặc bộ đệm. :) Nó hoạt động với giao diện điều khiển, bởi vì giao diện điều khiển chấp nhận bất cứ điều gì. Ví dụ đơn giản:

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

Một cách để chuyển đổi bất cứ điều gì để chuỗi là để làm điều đó:

res.write("" + obj); 

bất cứ khi nào bạn đang cố gắng để gửi một cái gì đó. Cách khác là gọi phương thức .toString():

res.write(obj.toString()); 

Lưu ý rằng nó vẫn không thể là thứ bạn đang tìm kiếm. Bạn nên luôn chuyển chuỗi/bộ đệm đến .write mà không cần các thủ thuật như vậy.

Lưu ý: Tôi giả định rằng request là một hoạt động không đồng bộ. Nếu đúng như vậy, thì res.end(); sẽ được gọi trước bất kỳ văn bản nào, tức là mọi văn bản sẽ không thành công (vì kết nối sẽ bị đóng tại thời điểm đó). Di chuyển dòng đó vào trình xử lý:

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

Cảm ơn rất nhiều câu trả lời và thông tin chi tiết. Và, vâng, tôi đã chuyển khoản gửi lại vào bộ xử lý. Tôi đã chấp nhận @loganfsmyth như trước đó. Thx lần nữa. – umutm

11

tôi nhận được thông báo lỗi này và nó đề cập đến options.body

Tôi có điều này ban đầu

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

tôi đã thay đổi nó như thế này:

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

và có vẻ như để làm việc bây giờ không thông báo lỗi ...có vẻ như lỗi mặc dù

+2

Vấn đề của bạn là khác nhau, cơ thể được mong đợi theo mặc định là một chuỗi hoặc bộ đệm. Bạn cũng có thể thay đổi nó (thành json serializable) thêm json: true vào các tùy chọn. Ví dụ: request.post ({ url: apiServerBaseUrl + '/ v1/xác minh', cơ thể: {email: req.user.email}, json: true }) –

+0

Bạn có thể sử dụng điều này để tránh * * stringify ** '' 'javascript request.post ({ url: apiServerBaseUrl + '/ v1/xác minh', json: { email: req.user.email }} ' '' – bsorrentino

0

nếu u muốn viết một đối tượng JSON để phản ứng sau đó thay đổi kiểu nội dung tiêu đề để 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(); 
Các vấn đề liên quan