I am trying to learn and understand nodejs. While trying to connect to api of Twitter stream and track tweets, I get following error :
undefined:1
<html>\n<head>\n<meta http-equiv="Content-Type" content="text/html; charset=ut
^
SyntaxError: Unexpected token <
at Object.parse (native)
at IncomingMessage.<anonymous> (/home/ytsejam/public_html/nodejs/11/twitter.js:15:20)
at IncomingMessage.emit (events.js:95:17)
at IncomingMessage.<anonymous> (_stream_readable.js:764:14)
at IncomingMessage.emit (events.js:92:17)
at emitReadable_ (_stream_readable.js:426:10)
at emitReadable (_stream_readable.js:422:5)
at readableAddChunk (_stream_readable.js:165:9)
at IncomingMessage.Readable.push (_stream_readable.js:127:10)
at HTTPParser.parserOnBody [as onBody] (http.js:142:22)
here is my code which I try to connect :
var https = require("https");
var options = {
host: 'stream.twitter.com',
path: '/1.1/statuses/filter.json?track=bieber',
method: 'GET',
headers: {
"Authorization": "Basic " + new Buffer("username:password").toString("base64")
}
};
var request = https.request('https://stream.twitter.com/1.1/statuses/filter.json?track=query', function(response){
var body = '';
response.on("data", function(chunk){
var chunk = chunk.toString();
try {
var tweet = JSON.parse(chunk);
} catch (err) {
console.log("JSON parse error:" + err);
}
console.log(tweet.text);
});
response.on("end",function(){
console.log("Disconnected");
});
});
request.end();
I did a research and tried to debug. my best guess is var tweet = JSON.parse(chunk); may cause problems. second option, I am missing oauth parameters.
Can you help me ? Thanks.
Edit :
I solved this using answer here Node.js and Twitter API 1.1
JSON.parse() is throwing a SyntaxError because the data it is trying to parse is HTML and not JSON.
In general, it's a good idea to wrap JSON.parse() in a try/catch block so you can handle those sorts of things gracefully.
(It is possible that there is a problem in your oauth stuff and it is failing to authenticate. So instead of getting JSON, you are getting an HTML page telling you that authentication has failed. But that is just a guess.)
Related
I am making an Ajax Post request:
$.ajax({
type:"POST",
dataType:"json",
contentType: "application/json",
data:newWorkLog,
url:"/add",
})
.done(function(response){
console.log("Response of update: ",response)
})
.fail(function(xhr, textStatus, errorThrown){
console.log("ERROR: ",xhr.responseText)
return xhr.responseText;
});
and was expecting to pass that newWorkLog object to an API method through my node.js server:
var bodyParser = require('body-parser');
app.use(bodyParser.json())
app.post('/add', function(req, res){
console.log(req.body) //This doesnt output anything
res.send(JSON.stringify(req.body));
});
After trying some approaches, I decided to only check what is being sent to my server.
Doing this, the message I get is:
SyntaxError: Unexpected token # in JSON at position 0
at JSON.parse (<anonymous>)
at createStrictSyntaxError (C:\working\app\node_modules\body-parser\lib\types\json.js:157:10)
at parse (C:\working\app\node_modules\body-parser\lib\types\json.js:83:15)
at C:\working\app\node_modules\body-parser\lib\read.js:121:18
at invokeCallback (C:\working\app\node_modules\raw-body\index.js:224:16)
at done (C:\working\app\node_modules\raw-body\index.js:213:7)
at IncomingMessage.onEnd (C:\working\app\node_modules\raw-body\index.js:273:7)
at emitNone (events.js:106:13)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1055:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
When I console.log my newWorkLog object, I can see from my client side, the correct json object.
when I check the param on the console I see the request payload and it looks like:
user%5Bid%5D=109&user%5BuserName%5D=myname
What could be causing that error?
You say newWorkLog is an object so you need to convert it to json to send it in your request.
$.ajax({
type:"POST",
dataType:"json",
contentType: "application/json",
data:JSON.stringify(newWorkLog),
url:"/add",
})
.done(function(response){
console.log("Response of update: ",response)
})
.fail(function(xhr, textStatus, errorThrown){
console.log("ERROR: ",xhr.responseText)
return xhr.responseText;
});
I am new to node.js. I have a requirement to proxy a POST request (with payload) to another server from node.js and process its response back to the browser client.
my scenario (browser <-> node.js <-> final destination server).
This is how my code looks, before i explain my issue.
app.post('^*$', function(req, res) {
delete req.headers.host; // i read somewhere to delete the old host
req.headers.host = 'ipadress:port';
request({ url: 'http://ipaddress:port' + req.path, headers: req.headers, body: req.body }, function(err, remoteResponse, remoteBody) {
if (err) { return res.status(500).end('Error no response'); }
res.writeHead(200,{
'Content-Length': remoteBody.length,
'Content-Type': 'text/xml' }); // copy all headers from Response
res.end(remoteBody);
});
});
I keep on getting "500 internal server error" "Error no response".
I strongly suspect (although not sure!) , the reason for this error is my payload from initial request is not being copied to the proxied request and the complete url which my final server expects is not there.
Can someone advise me, how i can copy the url and payload to the forwarding request ?
Also, how do i handle the response back from the forwarding serer ?
My payload is a xml object and final url is
http://ipaddress:port/XISOAPAdapter/MessageServlet?senderParty=&senderService=BS_WSAPPS_Q&receiverParty=&receiverService=&interface=SI_OrderStatusRequest_Out&interfaceNamespace=http://xyz/IF027/EC/OrderStatus/I_WS_APPS
#Krzysztof Sztompka.
Here is the information you asked me to put. miine is a dev environment.
_http_outgoing.js:512
throw new TypeError('first argument must be a string or Buffer');
^
TypeError: first argument must be a string or Buffer
at ServerResponse.OutgoingMessage.end (_http_outgoing.js:512:11)
at Request._callback (D:\MyNode.js\serverproxy.js:18:43)
at self.callback (D:\MyNode.js\node_modules\request\request.js:198:22)
at Request.emit (events.js:107:17)
at Request.onRequestError (D:\MyNode.js\node_modules\request\request.js:867:8)
at ClientRequest.emit (events.js:107:17)
at Socket.socketOnEnd (_http_client.js:300:9)
at Socket.emit (events.js:129:20)
at _stream_readable.js:908:16
at process._tickCallback (node.js:355:11)
Here is my code:
utilitesRouter.route('/url')
.post(function(request, response) {
console.log(request.body.uri);
var urlOpts = { host: request.body.uri, path: '/', port: '80', method: 'GET' };
var re = /(<\s*title[^>]*>(.+?)<\s*\/\s*title)>/gi;
http.get(urlOpts, function (response) {
response.on('data', function (chunk) {
var str=chunk.toString();
console.log(str);
var match = re.exec(str);
if (match && match[2]) {
console.log(match[2]);
}
});
});
response.json({ url: request.body.uri });
});
If I use POST request with this JSON {"uri":"google.ru" } I get:
302 Moved
google.ru
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
here.
</BODY></HTML>
If I use POST requiet with JSON {"uri":"http://google.ru" } I get the error message:
events.js:85
throw er; // Unhandled 'error' event
^
Error: getaddrinfo ENOTFOUND http://google.ru
at errnoException (dns.js:44:10)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:94:26)
I can open http://google.ru in my browser.
How can I get the HTML using node.js ?
You may want to request to do that. It just pretty easy.
var request = require("request");
router.get('/proxy', function(req, res, next){
request.get( req.body.uri, function(error, response, body){
if( error )
return next(error);
res.send(body);
});
});
request also support streaming and other cool features too.
You get the error because in your urlOpts the attribute host has to be a domain name, like google.ru or www.google.ru. As you are putting a URL into it, it can't be resolved to an IP via DNS, that's why you get the error at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:94:26).
If you want to use http.get() like the way you do, you would always have to extract the domain part out of your passed uri, i.e. getting google.ru out of http://google.ru to use it as host.
I have been playing around with the youtube API and node.js, so far I have been able to get a response from the API and console.log it onto the terminal.
When I try to get the response and use JSON.parse, I get a weird error:
Got response: 200
undefined:1
http://www.w3.or
^
SyntaxError: Unexpected token u
at Object.parse (native)
at IncomingMessage.<anonymous> (/home/ubuntu/node_temp4/index.js:19:10)
at IncomingMessage.emit (events.js:88:20)
at HTTPParser.onMessageComplete (http.js:137:23)
at Socket.ondata (http.js:1137:24)
at TCP.onread (net.js:354:27)
This is my script:
var http = require("http");
var searchQuery = "cats";
var queryResponse;
var options = {
host: 'gdata.youtube.com',
path: "/feeds/api/videos?q=" + searchQuery + "&max-results=1&v=2&alt=json"
};
http.get(options, function(response) {
console.log("Got response: " + response.statusCode);
response.on('data', function(chunk){
queryResponse += chunk;
});
response.on('end', function(){
JSON.parse(queryResponse);
console.log('end');
});
}).end();
The variable queryResponse is set to undefined and you are doing queryResponse += chunk in the 'data' envent handler which means queryResponse = queryResponse + chunk so you get
undefined{"youtube":["Api", "response"]}
you can fix it by instantiating queryResponse as an empty string var queryResponse = ''
I'm using the knox amazon uploader as a "proxy" to upload a sliced file from Javascript.
But the thing that've noticing is that sometimes ( sadly sometimes so I cannot identify the error exactly) when the response.statusCode isn't 200 the nodeJS crashes at an exception:
assert.js:93 throw new assert.AssertionError({
AssertionError: true == false at IncomingMessage.
(http.js:1341:9) at IncomingMessage.emit (events.js:61:17) at
HTTPParser.onMessageComplete (http.js:133:23) at Socket.ondata
(http.js:1231:22) at Socket._onReadable (net.js:683:27) at
IOWatcher.onReadable [as callback] (net.js:177:10)
Does anyone knows why this happens? Is there a way to catch that exception avoiding the server to crash?
Here's some code if it helps:
var request = client.request('PUT', '/' + params.fileName + '?partNumber=' + params.partNumber + '&uploadId=' + params.uploadId, {
'Content-Length': req.headers['content-length']
});
req.on('data', function(data){
request.write(data, 'binary');
});
request.on('response', function(response) {
if (response.statusCode== 200) {
console.log('Part '+ params.partNumber + ' inserted with etag: '+ response.headers.etag);
}
}).end();
This looks to be a bug in node.js < v0.5 where Socket.destroySoon() does not close the socket right away.
https://github.com/joyent/node/issues/1892