Permanently change html file using AJAX call on node.js server - ajax

How do I write a script to permanently change a static html file after making an ajax call to the node.js server? Any examples would be greatly appreciated :)

I agree with NikxDa that this is probably not the best solution for you, but this code should do the trick.
/write.js
var http = require('http');
var fs = require('fs');
var url = require('url');
//Lets define a port we want to listen to
const PORT=8080;
function handleRequest(request, response){
var path = url.parse(request.url).pathname;
if(path=="/write"){
fs.appendFile('message.html', 'Node.js!', function (err) {
if (err) throw err;
console.log('It\'s saved!');
});
} else {
fs.readFile('index.html',function (err, data){
response.writeHead(200, {'Content-Type': 'text/html','Content-Length':data.length});
response.write(data);
response.end();
});
}
}
// Create a server.
var server = http.createServer(handleRequest);
server.listen(PORT, function(){
console.log("Server listening on: http://localhost:%s", PORT);
});
/index.html
<!DOCTYPE html>
<head>
<script>
function writeIt()
{
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET","http://localhost:8080/write", true);
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
string=xmlhttp.responseText;
document.write(string + ": Saved change to message.html");
}
}
xmlhttp.send();
}
</script>
</head>
<body>
<p>Click the button to send an AJAX request to `write.js`<p>
<br><button onclick="writeIt()">Click Me</button>
</body>
/message.html
Node.js!

Editing the file directly via node would probably be really bad, I do not even know if it is at all possible. I think the better solution is for your Node Server to make the data you want to change accessible and then use jQuery or Angular to update the HTML-File when it is actually loaded.
Another approach would be to use a templating engine like https://github.com/tj/ejs, and then serve the file via Node directly, so you can change the data in the Node-Application itself every time.

Related

Accessing socket.io in koa route

I'm trying to use socket.io with koa.js and I was able to connect adding server = require('http').createServer(koa.callback()).listen(port); and io = require('socket.io')(server); at the very bottom of my application but now I want to emit and if possible listen to events from my controller / route. What's the best way to implement this?
I've tried adding io in my koa context like koa.context.io = io and even io.on('connection', function(socket){ koa.context.socket = socket }); but nothing is working.
Thanks in advance guys.
Accessing the socket.io instance in your koa route should not work.
Creating the socket.io instance depends on the application creating a callback function that can be used by the http server.
var server = http.createServer(app.callback());
var io = require('socket.io')(server);
This callback is generated with the help of co and requires that your app is already set up with all the middleware/routes. (see the koa source). Therefore you can't use the socket.io instance (which is created afterwards) in those routes.
Furthermore I think it is not intended to emit socket.io events in your controllers. If you want to send data back to the client that called the controller, you should do it in the response which is generated by that controller. If you want to emit further events at the server you could trigger them from the client by emitting an event that the server will receive. This way you can process the data from the client in the function you pass to socket.on(...) and don't need to implement it in the controller/routes for koa.
Here is an example for the second case, without any koa controller/route.
app.js:
var http = require('http');
var koa = require('koa');
var app = koa();
var send = require('koa-send');
app.use(function* (next) {
if (this.path !== '/') return yield next;
yield send(this, __dirname + '/index.html');
});
var server = http.createServer(app.callback());
var io = require('socket.io')(server);
io.on('connection', function (socket) {
socket.on('click', function (data) {
//process the data here
console.log('client clicked! data:');
console.log(data);
// emit an event
console.log('responding with news');
socket.emit('news', { hello: 'world' });
});
});
var port = process.env.PORT || 3000;
server.listen(port);
console.log ('Listening at port ' + port + ' ...');
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>koa-socket.io</title>
</head>
<body>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io('http://localhost:3000');
socket.on('news', function (data) {
console.log('received news with data: ');
console.log(data);
});
function myclick () {
console.log("click");
socket.emit('click', { clickdata: 'i clicked the button' });
}
</script>
<button type="button" onclick="myclick();">Click Me and watch console at server and in browser.</button>
</body>
</html>
I realise this is a little late on the uptake, and could be deemed slightly self-serving as I'm going to suggest one of my own modules, but, you're on the right track with appending it to the app, with Koa v2 this is easier as the context is passed right along but with v1 you can tack it onto this, as koa middleware's are bound to the app instance.
Alternatively, I wrote a module to help with this exact use-case, https://github.com/mattstyles/koa-socket, it does just 2 things currently (and probably forever): it appends the socket.io server instance to the context and it allows you to write koa-style middleware for your socket listeners.

Fetch terminal command (Nodejs) and send to specific port via AJAX

I'm actually working on a little application. I have one server written in C which is listening on the port 5260. In the other side I have a NodeJS client which is listening on the port 7777. A HTML page can be reach via this port. In the HTML page I have a simple button.
When I click on this one a message is sent to my NodeJS server and is written on the terminal. Now I would like to fetch this command and send it to my C server which is still running and waiting for a request.
My client.js :
var http = require('http');
var ejs = require('ejs');
var express=require('express');
var app = express();
app.engine('html', ejs.renderFile);
app.set('/', __dirname);
app.get('/', function(request,response) {
response.render('index.ejs.html');
})
var options = {
host: '192.168.1.154',
path: '/',
port: '5260',
method: 'POST'
};
app.post('/play', function(req, res){
var res = http.request(options);
console.log("START_BG;BG1\n");
});
app.listen(7777);
And my HTML file :
<html>
<head>
<script type="text/javascript" src="client.js"></script>
<script type="text/javascript">
function sendMessage() {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/play', true);
xhr.onload = function() {
console.log(xhr);
};
xhr.send();
}
</script>
</head>
<body>
<button onclick="sendMessage()">VIDEO</button>
</body>
</html>
Well. I see some strange things in your code
1 You're making the post request to 192.168.1.254:5620/play without sending any data on it
2 You're not waiting fro the request to end and blindly print on your console without checking the result. Don't know if its the desired behaviour, but it seems a bit strange
Without more knowledge about the scenario is difficult to suggest an idea.
What is the answer you expect from the remote server?
It's suposed to print something in the (remote) console ?
What it should return via HTTP ?
Anyway I suggest you correct your code as follows:
app.post('/play', function(req, res){
var res = http.request(options, function(response){
// do any checking about response status and/or body if any
console.log("START_BG;BG1\n");
});
});

a file upload progress bar with node (socket.io and formidable) and ajax

I was in the middle of teaching myself some Ajax, and this lesson required building a simple file upload form locally. I'm running XAMPP on windows 7, with a virtual host set up for http://test. The solution in the book was to use node and an almost unknown package called "multipart" which was supposed to parse the form data but was crapping out on me.
I looked for the best package for the job, and that seems to be formidable. It does the trick and my file will upload locally and I get all the details back through Ajax. BUT, it won't play nice with the simple JS code from the book which was to display the upload progress in a progress element. SO, I looked around and people suggested using socket.io to emit the progress info back to the client page.
I've managed to get formidable working locally, and I've managed to get socket.io working with some basic tutorials. Now, I can't for the life of me get them to work together. I can't even get a simple console log message to be sent back to my page from socket.io while formidable does its thing.
First, here is the file upload form by itself. The script inside the upload.html page:
document.getElementById("submit").onclick = handleButtonPress;
var httpRequest;
function handleResponse() {
if (httpRequest.readyState == 4 && httpRequest.status == 200) {
document.getElementById("results").innerHTML = httpRequest.responseText;
}
}
function handleButtonPress(e) {
e.preventDefault();
var form = document.getElementById("myform");
var formData = new FormData(form);
httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = handleResponse;
httpRequest.open("POST", form.action);
httpRequest.send(formData);
}
And here's the corresponding node script (the important part being form.on('progress')
var http = require('http'),
util = require('util'),
formidable = require('formidable');
http.createServer(function(req, res) {
if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
var form = new formidable.IncomingForm(),
files = [],
fields = [];
form.uploadDir = './files/';
form.keepExtensions = true;
form
.on('progress', function(bytesReceived, bytesExpected) {
console.log('Progress so far: '+(bytesReceived / bytesExpected * 100).toFixed(0)+"%");
})
.on('file', function(name, file) {
files.push([name, file]);
})
.on('error', function(err) {
console.log('ERROR!');
res.end();
})
.on('end', function() {
console.log('-> upload done');
res.writeHead(200, "OK", {
"Content-Type": "text/html", "Access-Control-Allow-Origin": "http://test"
});
res.end('received files: '+util.inspect(files));
});
form.parse(req);
} else {
res.writeHead(404, {'content-type': 'text/plain'});
res.end('404');
}
return;
}).listen(8080);
console.log('listening');
Ok, so that all works as expected. Now here's the simplest socket.io script which I'm hoping to infuse into the previous two to emit the progress info back to my page. Here's the client-side code:
var socket = io.connect('http://test:8080');
socket.on('news', function(data){
console.log('server sent news:', data);
});
And here's the server-side node script:
var http = require('http'),
fs = require('fs');
var server = http.createServer(function(req, res) {
fs.createReadStream('./socket.html').pipe(res);
});
var io = require('socket.io').listen(server);
io.sockets.on('connection', function(socket) {
socket.emit('news', {hello: "world"});
});
server.listen(8080);
So this works fine by itself, but my problem comes when I try to place the socket.io code inside my form.... I've tried placing it anywhere it might remotely make sense, i've tried the asynchronous mode of fs.readFile too, but it just wont send anything back to the client - meanwhile the file upload portion still works fine. Do I need to establish some sort of handshake between the two packages? Help me out here. I'm a front-end guy so I'm not too familiar with this back-end stuff. I'll put this aside for now and move onto other lessons.
Maybe you can create a room for one single client and then broadcast the percentage to this room.
I explained it here: How to connect formidable file upload to socket.io in Node.js

How to send data from server to client via http?

I want to send the filepath of a file on my server to the client in order to play it using a media player. How can I retrieve that string on the client side in order to concatenate it in the src attribute of a <video element without using sockets?
Server snippet:
res.set('content-type', 'text/plain');
res.send('/files/download.mp4');
This is how you make a request to the server without any frameworks. "/path_to_page" is the route you set to the page that is supposed to process the request.
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path_to_page', true);
xhr.onload = function(e) {
if (this.status == 200) {
console.log(this.responseText); // output will be "/files/download.mp4"
}
};
xhr.send();
}
You might also want to send some params.
var formdata = new FormData();
formdata.append("param_name", "value");
So you might for instance want to send the filename or such.
You just need to change 2 lines from the first code snippet. One would be
xhr.open('POST', '/path_to_page', true); // set to post to send the params
xhr.send(formdata); // send the params
To get the params on the server, if you are using express, they are in req.body.param_name
Which framework are you using??
You can declare base path of your project directory in ajax and the followed by your file.
jQuery.ajax({
type: "GET",
url: "/files/download.mp4",
});
Since you are using express (on node), you could use socket.io:
Server:
var io = require('socket.io').listen(80),
fs = require('fs');
io.sockets.on('connection', function (socket) {
socket.on('download', function(req) {
fs.readFile(req.path, function (err, data) {
if (err) throw err;
socket.emit('video', { video: data });
});
});
});
Client:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
...
// request a download
socket.emit('download', { path: '/files/download.mp4' });
// receive a download
socket.on('video', function (data) {
// do sth with data.video;
});
...
</script>
Edit: didnt notice you didnt want to use sockets. Still it is a viable solution.

Looking for an extremely simple AJAX script

I need a very basic, simple and lightweight AJAX script.
Does anyone have a shell of such a script they can share?
Here's what I have:
I have a PHP script on the server that echo's the current date and time on the server
I just need the javascript that calls the php script and loads the echoed text string into a js var so I can use it in my app
(the reason I need the server's clock is that all visitors to the site have to work off the same clock. The app does not work for visitors outside the server's timezone.)
Thanks for helping out.
JQuery is perhaps the right answer for AJAX but you can also do this in plain old Javascript as follows:
<html>
<head>
<script type="text/javascript">
function loadXMLDoc(){
var xmlhttp;
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
//the callback function to be callled when AJAX request comes back
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
  }
}
xmlhttp.open("POST","<<url of web address>>",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("fname=Henry&lname=Ford");
}
</script>
</head>
<body>
<h2>AJAX</h2>
<button type="button" onclick="loadXMLDoc()">Request data</button>
<div id="myDiv"></div>
</body>
</html>
You can find a simple example here:
AjaxCall = function(Data, WebServiceURL, Callback) {
var request;
var url = WebServiceURL;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState === 4) {
if (request.status === 200) {
Callback(request);
} else {
alert("Sorry, an error occurred. " + request.responseText);
}
}
};
request.open("POST", url, true);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.send(Data);
} else if (window.ActiveXObject) {
url += "?" + Data;
request = new ActiveXObject("Microsoft.XMLHTTP");
if (request) {
request.onreadystatechange = function() {
if (request.readyState === 4) {
if (request.status === 200) {
Callback(request);
} else {
alert("Sorry, an error occurred. " + request.responseText);
}
}
};
request.open("GET", url, true);
request.send();
}
}
};
The the ajax functionality in jQuery is great but does mean a greater page download for one simple Javascript function.
You can find a downloadable fully worked example on my blog here:
http://www.willporter.co.uk/blog/simple-ajax-script.aspx
It uses ASP.NET on the server side but you should get the idea.
jQuery has made very simple ajax methods for you to use. You can find more information about them here.
Sample:
$.ajax({
type: 'GET',
url: '/SomeUrl/On/The/Server',
data: { SomeValue: 10 },
success: function(data, status)
{
// On Success
},
error: function(data, status)
{
// On Error
}
});
Look into this maybe : http://www.scriptiny.com/2011/01/simple-ajax-function-example/
jQuery is a more reliable library overall, but the lightest-weight AJAX methods I have found are the extremely simple Feather AJAX, coming in at 1.6 KB (with room for compression), or a one-liner snippet that I can't guarantee.
The risk of extremely lightweight libraries is that if they break, you're relying on the owner to fix it instead of a team of developers.
An alternative approach to solving your problem is to based your times on UTC instead of server-local time. You can even show the client local times based on that utc time, with a little work.
May I suggest AJAX Generator?
I am developer, and it is commercial tool but it has demo as well.
What you could do with that tool is:
put annotation on your PHP function
run AJAX Generator on PHP source file
include generated JavaScript file in HTML page and use PHP service as if you were calling function
To make it more clear, here is example code:
//example.php
<?php
//#WebService
function getServerDate(){
return date('m/d/Y h:i:s a', time());
}
?>
Now run generator on: example.php
Output would be two files: example_service.php and example_caller.js
Now you need to:
add example_service.php in same directory where is example.php and
include example_caller.js in index.html
Sorry for posting image instead of HTML code, but it wasn't showing properly.

Resources