Elegant way to send form data to node.js - node-static - javascript

I try to send some data to my node.js / node-static app and store it in a file.
Right now i use a basic html form and capture the pathfile:
Server side:
var daten = url_parts.query;
if (pathfile== '/get.htm'){ // get.htm just redirects back to form
console.log('Device 1:', daten);
fs.writeFile("devices.txt", devices(daten), function(err) {
if(err) {console.log(err);} else {console.log("The file was saved!");}
});
}
I feel dirty using this but i am a bit overwhelmed by the possibilities to perform such a simple task.
Using jQuery seems the way to go.
My problem: How can I send the data without a page refresh or redirecting to another page? What is the elegant way? Where do I perform the 'magic'?
Client or Server side?

I ended up restructuring server and client side. Maybe someone finds this useful or can improve this suggestion:
Server:
if (pathfile== '/get.json'){
fs.writeFile("devices.txt", devices(daten), function(err) {
if(err) {console.log(err);} else {console.log("The file was saved!");}
});
response.writeHead(200, { "Content-type": "application/json" });
response.end();
return;
}
Client:
$('#enter').click(function(){
var data = $('form').serialize() ;
$.ajax({
type: "get",
url: "get.json",
data: data,
success: function(){alert('data was send!');},
error: function(){alert('server not responding!');}
});
return false;
});

Related

Ajax request not working in loopback

I am beginner in loopback and working on Get Post in loopback
This is code on client side
var datas = 'Something';
$.ajax({
type: 'POST',
url: '/post',
data: datas,
dataType: 'text'
})
.done(function(data) {
console.log('Successful');
.fail(function(jqXhr) {
console.log('Failed');
});
and this is on server side(server.js)
app.post('/post', function(req, res){
console.log('This is DATA '+ req.body);
});
This is not working it gives me 404 not found or failed.
What am I doing wrong and Is there another method for get post in loopback?
the server side needs an server and listening a port.
the client side needs to listen another port.
so they are not in one domain and cannot get access to each other.
this called a "cross-origin requests"
check this for the solution:https://www.w3.org/TR/cors/
Your URL starts with '/'.
Whenever a URL starts with '/' it is treated as absolute URL.
Whereas, most of the time, web apps are bounded with a context root.
Try using URL without initial '/' and it should work.

Server sends data to client

In my express project I want my server to send a JSON object to the client. The client uses a script to display the data it recieves and so I dont want to the data sent from the server being seen on the screen directly, I want it to go through the javascript first.
I tried many ways to send any data and non was successfull:
client:
$.get('http://localhost:1337/', {mydata: 'content'}, function(response){
console.log(response);
});
or
$.ajax({
url: 'http://localhost:1337/',
data: {
mydata: "content"
},
dataType: 'json',
success: function (json) {
console.log(json);
},
error: function (jqXHR, error, errorThrown) {
console.log(error);
},
type: 'GET'
});
server:
app.get('/', function (req, res) {
res.render('main',{data:'text'})
});
or
app.get('/', function (req, res) {
res.render('main','text2')
});
Is there a way to send data to the client that will go first to the javascript in the sended page?
Thank you!
On your server, use res.json({data:'text'}); instead of res.render(...) to send json. That should do the trick.
Update:
If you want to build a single page application with multiple ajax requests you should use different routes for those. One will send the page and the other the data.
However, if your application is small and simple, you could continue doing what you did, but get the data via javascript variable instead of an ajax request. For that in your template you'll have to do something like that (assuming it's jade):
script(type='text/javascript')
var local_data =!{JSON.stringify(data)};
The page will be rendered with the following HTML:
<script type="text/javascript">
var local_data = {"data":"text"};
</script>
You than in your script can do the following:
//Your javascript
function displayPage(data){
//display logic here
console.log(data);
}
displayPage(local_data);

Does res.writehead actually write to the head of my html page?

In my node.js webpage I'm making a page preview similar to the Facebook link preview. I'm making a call to get the html of the page, and use it to create the preview.
$.ajax({
type: 'GET',
data: { "html": url },
url: "/htmlTest",
success: function (data) {
imgArray = [];
$('img', data).each(function () {
imgArray.push(this.src);
});
...
This is the server-side code that handles the request.
app.get('/htmlTest', function (req, res) {
res.writeHead(200, { 'content-type': 'text/html' });
request(req.query.html, function (error, response, body) {
if (error) {
res.write(error.toString());
res.end('\n');
}
else if (response.statusCode == 200) {
res.write(body);
res.end('\n');
}
})
});
Now what I've been noticing, is that it will just insert any css the other page uses into my page, which can really screw everything up. Why is this happening?
Also, while I'm at it, does anyone have any better ideas for a facebook-style page preview?
No. writeHead writes HTTP headers to the underlying TCP stream. It has absolutely nothing to do with HTML.
You're running into an issue because your server returns the wholesale HTML content of the requested URL. You then pass this string into jQuery, which is apparently adding contained CSS styles into your document.
Generally, it is a terrible idea to take random code from a user-supplied URL and run in the context of your page. It opens you to gaping security holes – the CSS artifacts you're seeing are one example.
To be blunt, your code has numerous problems, so bear with me as I point out some issues.
app.get('/htmlTest', function (req, res) {
res.writeHead(200, { 'content-type': 'text/html' });
Here, you respond to the browser with a success status (200) beore your server actually does anything. This is incorrect: you should only respond with either a success or error code after you know if the request succeeded or failed.
request(req.query.html, function (error, response, body) {
if (error) {
res.write(error.toString());
res.end('\n');
}
Here would be a good place to respond with an error code, since we know that the request did actually fail. res.send(500, error) would do the trick.
else if (response.statusCode == 200) {
res.write(body);
res.end('\n');
}
And here's where we could respond with a success code. Rather than use writeHead, use Express's set and send methods – things like Content-Length will be correctly set:
res.set('Content-Type', 'text/html');
res.send(body);
Now what happens if response.statusCode != 200? You don't handle that case. error is only set in the case of network errors (such as inability to connect to the target server). The target server can still respond with a non-200 status, and your node server would never respond to the browser. In fact, the connection would hang open until the user kills it. This could be fixed with a simple else res.end().
Even with these issues resolved, we still haven't addressed the fact that it's not a good idea to try to parse arbitrary HTML in the browser.
If I were you, I'd use something that parses HTML into a DOM on the server, and then I'd return only the necessary information back to the browser as JSON. cheerio is the module you probably want to use – it looks just like jQuery, only it runs on the server.
I'd do this:
var cheerio = require('cheerio'), url = require('url'), request = require('request');
app.get('/htmlTest', function(req, res) {
request(req.query.url, function(err, response, body) {
if (err) res.send(500, err); // network error, send a 500
else if (response.status != 200) res.send(500, { httpStatus: response.status }); // server returned a non-200, send a 500
else {
// WARNING! We should probably check that the response content-type is html
var $ = cheerio.load(body); // load the returned HTML into cheerio
var images = [];
$('img').each(function() {
// Image srcs can be relative.
// You probably need the absolute URL of the image, so we should resolve the src.
images.push(url.resolve(req.query.url, this.src));
});
res.send({ title: $('title').text(), images: images }); // send back JSON with the image URLs
}
});
});
Then from the browser:
$.ajax({
url: '/htmlTest',
data: { url: url },
dataType: 'json',
success: function(data) {
// data.images has your image URLs
},
error: function() {
// something went wrong
}
});

How to catch JSON object when server and client on the same system

I made HTML page that have form, when submitting, it calls JavaScript by using this event handler.
onClick = operation(this.form)
and the JavaScript is:
function operation(x) {
//url:"C:\Users\jhamb\Desktop\assignment_1_18_1_13\question_3\ques\form1.html",
url:"http://localhost:8080",
$.ajax({
data:{
comment:x.comment.value, // information from html page
email: x.email.value, // information from html page
url:x.url.value, // information from html page
name:x.name.value, // information from html page
}
}).done(function(serverResponse){
alert("response is ready"); //here you can handle server response
}).fail(function(err){
alert("ohhh!!! there is some error"); //here you can handle errors
});
//alert(obj.details[3].comment_value);
}
Now what I want is to communicate between server and client , that is on same system.
My code is not working. Now what can I do, please help.
first i don't think your server listens on port 8080, that normaly aport for the admin software.
second you have to put the url inside the ajax request
function operation(x) {
//url:"C:\Users\jhamb\Desktop\assignment_1_18_1_13\question_3\ques\form1.html",
$.ajax({
url:"http://localhost:8080",
data:{
comment:x.comment.value, // information from html page
email: x.email.value, // information from html page
url:x.url.value, // information from html page
name:x.name.value, // information from html page
}
}).done(function(serverResponse){
alert("response is ready"); //here you can handle server response
}).fail(function(err){
alert("ohhh!!! there is some error"); //here you can handle errors
});
//alert(obj.details[3].comment_value);
}
you shoul also add dataType (html or json), the sending type (post, get etc.) in the param list
Maybe it will help if you modify tour code slightly:
function operation(x) {
$.ajax({
url: "http://localhost:8080",
data: $(x).serialize(),
}).done(function (serverResponse) {
alert("response is ready");
}).fail(function (err) {
alert("ohhh!!! there is some error");
});
}

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