Sending and recieving plain text instead of an object with node http - javascript

I'm incredibly new at trying to do anything relating to webservers and the like and I've gotten stuck trying to send data from a javascript that runs on a website to a server that runs locally. I've been able to get them to communicate, but all the data I get on the server is always just "[object object]" instead of the string that I send from the browser.
This is how the server is looking currently, very bareboned:
http.createServer(function(request, response){
response.writeHead(200, {"Content-Type": "text/plain"});
console.log("request recieved: " + response + request);
}).listen(8001);
And this is what i send from the browser:
var url = "http://localhost:8001";
$.ajax({
url: url,
type: "POST",
data: "Hello friend",
contentType: "text/plain",
});
I've also tried something like this which results in the same problem:
var http = new XMLHttpRequest();
var sendData = "HELLO";
http.open("POST", "http://localhost:8001", true);
http.setRequestHeader("Content-type", "text/plain");
http.send(sendData);
I've also tried to use JSON.stringify on the server-side to try to get the string, but this returns an error stating that it cannot be used on a 'circular object'.
I'm sorry if this question is really stupid, as I said, I'm a complete beginner and this is the first time I've tried to do something remotely similar. I've tried researching what to do differently, but after trying countless options I felt that I needed to ask here instead.
Thanks in advance! And if any more information is needed I'd be happy to try to expand on the issue!

When you use concatenation (+) operator then javascript will convert object to string. Default String representation of object is [object object]. That's why it's printing [object object].
http.createServer(function(request, response){
response.writeHead(200, {"Content-Type": "text/plain"});
console.log("request recieved: " , response , request);
}).listen(8001);
And if you want to get the body then you have the listen to data event and consume the data.
http
.createServer(function(request, response) {
let body = "";
request.on("data", chunk => {
body += chunk.toString(); // convert Buffer to string
});
request.on("end", () => {
console.log(body);
response.end('ok');
});
})
.listen(8001);
I will recommend to use express package to avoid all boilerplate code.

You can access the body with request.body. You can't JSON.stringify the whole request because, as you saw, it holds ciruclar deps, but you can do so with the request.body.

Related

Access response body after multiple res.write()s

How do I access the response body after doing multiple res.write()s? Simplified example:
endpoint(req, res) {
res.set('Content-Type', 'application/json')
res.write('{"resdata":')
//Stream data, format it, and then add to the response
res.write(stream1)
res.write(', "resdata2":')
//Stream some other data, format it, and then add to the response:
res.write(stream2)
res.write('}')
var savedBody = res.getBody() //Is there a way to extract the response body here from all the res.writes()?
res.end()
doSomethingElseWithResponseBody(savedBody)
}
Technically, I could create my own JSON and then do a single res.send at the end -- I know -- but in the specific implementation of this, it's very difficult to use that method; the res.writes() need to be kept.
Appreciate any tips!

JavaScript Fetch: characters with encoding issues

I'm trying to use Fetch to bring some data into the screen, however some of the characters ares showing a weird � sign which I believe has something to do with converting special chars.
When debugging on the server side or if I call the servlet on my browser, the problem doesn't happen, so I believe the issue is with my JavaScript. See the code below:
var myHeaders = new Headers();
myHeaders.append('Content-Type','text/plain; charset=UTF-8');
fetch('getrastreiojadlog?cod=10082551688295', myHeaders)
.then(function (response) {
return response.text();
})
.then(function (resp) {
console.log(resp);
});
I think it is probably some detail, but I haven't managed to find out what is happening. So any tips are welcome
Thx
The response's text() function always decodes the payload as utf-8.
If you want the text in other charset you may use TextDecoder to convert the response buffer (NOT the text) into a decoded text with chosen charset.
Using your example it should be:
var myHeaders = new Headers();
myHeaders.append('Content-Type','text/plain; charset=UTF-8');
fetch('getrastreiojadlog?cod=10082551688295', myHeaders)
.then(function (response) {
return response.arrayBuffer();
})
.then(function (buffer) {
const decoder = new TextDecoder('iso-8859-1');
const text = decoder.decode(buffer);
console.log(text);
});
Notice that I'm using iso-8859-1 as decoder.
Credits: Schneide Blog
Maybe your server isn't returning an utf-8 encoded response, try to find which charset is used and then modify it in call headers.
Maybe ISO-8859-1 :
myHeaders.append('Content-Type','text/plain; charset=ISO-8859-1');
As it turns out, the problem was in how ther servlet was serving the data without explicitly informing the enconding type on the response.
By adding the following line in the Java servlet:
response.setContentType("text/html;charset=UTF-8");
it was possible got get the characters in the right format.

node.js POST callbacks not received

I am POSTing a json file to a node.js listener, and I must not fully understand how POSTs are properly constructed, because in the code below the on('data') callback is never invoked. I can see the actual json string in the body, so I can work around the lack of a callback, but it seems like I'm doing something wrong with how I generate my POST request. [Postman details further below]
// Server initialization
var server = restify.createServer();
server.use(restify.queryParser());
server.use(CookieParser.parse);
server.use(restify.bodyParser());
// Later, at the point where I register callbacks.
this.server.post('receive', function (request, respond) {
console.log('Received POST');
console.log("Headers: %s", JSON.stringify(request.headers));
console.log("Body: %s", JSON.stringify(request.body));
var body = '' ;
var filePath = './data/notes.json';
// this event is never triggered.
request.on('data', function (data) {
console.log('Data received.');
body += data;
});
request.on('end', function () {
console.log('End of POST');
fs.writeFile(filePath, body, function () {
respond.end();
});
});
});
POST details:
I'm using Postman to create a POST request, Content-Type: application/json and the putting the json string in the raw body. What will normally trigger the 'data' event in a POST request? If I ignore data events and just read from the request body, will I run into issues?
Since you're using restify.bodyParser, that middleware would have already read the request body so there isn't any more for your handler to read (hence no data events). A stream, like request, can only be read once, until it's exhausted. You can't "re-read" it.
Which also means that you can just use request.body, which should be the (parsed) result of the JSON that you're posting.
As an aside: I don't know Postman very well, but it looks like you're sending a JSON-encoded string to the server, as opposed to a JSON-encoded object.
To send the latter, I would expect that this should be the raw body data:
{"body":"this is a test"}

Difference between response.setHeader and response.writeHead?

In my application, I have my Nodejs server send a JSON response. I found two ways to do this but I'm not sure what the differences are.
One way is
var json = JSON.stringify(result.rows);
response.writeHead(200, {'content-type':'application/json', 'content-length':Buffer.byteLength(json)});
response.end(json);
And my other way is
var json = JSON.stringify(result.rows);
response.setHeader('Content-Type', 'application/json');
response.end(json);
Both ways work and I'm just wondering what the difference is between the two and when I should use one over the other.
response.setHeader() allows you only to set a singular header.
response.writeHead() will allow you to set pretty much everything about the response head including status code, content, and multiple headers.
Consider the NodeJS docs:
response.setHeader(name, value)
Sets a single header value for implicit headers. If this header already exists in the to-be-sent headers, its value will be replaced. Use an array of strings here to send multiple headers with the same name.
var body = "hello world";
response.setHeader("Content-Length", body.length);
response.setHeader("Content-Type", "text/plain");
response.setHeader("Set-Cookie", "type=ninja");
response.status(200);
response.writeHead(statusCode[, statusMessage][, headers]))
Sends a response header to the request. The status code is a 3-digit HTTP status code, like 404. The last argument, headers, are the response headers. Optionally one can give a human-readable statusMessage as the second argument.
var body = "hello world";
response.writeHead(200, {
"Content-Length": body.length,
"Content-Type": "text/plain",
"Set-Cookie": "type=ninja"
});

Node.JS http server with compression - sending variable as response

Sorry for the vague question.. but I'm not sure quite what the problem is.
I have a node http server that I'm using to serve JSON data to a web app. It works great, but my JSON strings are starting to get large(10-12 MB), so I want to add compression with zlib.
The JSON data is in a string variable and I want to compress and then write to the response object... but the results that go back to the client seem to always have with perfect headers, and no content. Here is my deliverResponse function:
var deliverResult = function (data, response, callback, acceptEncoding){
var payload = callback + '(' + JSON.stringify(data) + ');';
if (acceptEncoding.match(/\bdeflate\b/)) {
response.writeHead(200, { 'Content-Encoding': 'deflate', 'Content-Type': 'text/javascript; charset=UTF-8' });
zlib.deflate(payload, function(err, result){
if(!err){
//console.log(result.toString('utf8')); // I have data on the console here
response.write(result.toString('utf8')); // No data sent here
}
});
} else if (acceptEncoding.match(/\bgzip\b/)) {
response.writeHead(200, { 'Content-Encoding': 'gzip', 'Content-Type': 'text/javascript; charset=UTF-8' });
zlib.gzip(payload, function(err, result){
if(!err){
response.write(result.toString('utf8'));
}
});
} else {
writelog('INFO', 'Returning data without compression\n');
response.writeHead(200, { 'Content-Type': 'text/javascript; charset=UTF-8' });
response.write(payload);
}
response.end();
}
The http server examples with zlib use streams and the pipe function, but I'm not sending a file as I generate the JSON data in the app from a database, so I am basing this on the convenience method examples. My troubleshooting so far I know that the response object is good, and that result.toString('utf8') outputs gobeldy-gook as expected. If I don't send an acccept-encoding header to the server, it sends plain text perfectly - so it had got to be the compression functions.
Anyone have any idea about this? I'm pretty sure it has to to with my lack of understanding about streams, pipes, buffers and the zlib object, and it's probably just a syntax issue, so hopefully someone who understands all this can help me out :)
Cheers
Solved....
Stupid problem.. the response.write is being called in a async function, so it's doing the write.end() before the response.write and an empty response is sent... replaced the response.write with response.end in the callback and it works perfectly :)

Categories

Resources