AJAX request on Node.js server - html

I am unable to make an AJAX request from my .html page to my node.js server for a JSON file. I've been reading on AJAX requests, but all I am able to make out is how to display the servers responseText.
It would be great if you could help me out, it would be even better if you could link me some tutorials on this, anyway this is what I've got at this moment:
server.js
var express = require('express');
var fs = require('fs');
var app = express();
app.get('/test', function(req, res){
var arr = new Array();
var rd = readline.createInterface({
input: fs.createReadStream('info.json'),
output: process.stdout,
terminal: false
});
rd.on('line', function(line) {
arr.push(line);
}).on('close', function(){
res.send(arr);
});
});
app.get('/', function(req, res) {
fs.readFile('test2.html',function (err, data){
res.writeHead(200, {'Content-Type': 'text/html','Content-Length':data.length});
res.write(data);
res.end();
});
});
app.listen(process.env.PORT || 3000);
test.html
<html>
<head>
<script>
function sendAjax(){
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState==4 && xmlHttp.status == 200){
console.log(xmlHttp.responseText);
}
document.getElementById("myDiv").innerHTML=xmlHttp.responseText;
}
xmlHttp.open("GET", "/test", true);
xmlHttp.send();
}
</script>
</head>
<body>
<input type="submit" onClick="sendAjax()" value="SendAjax" />
<div id="myDiv"><h2>Let AJAX change this text</h2></div>
</body>
</html>
I know this may not look like much, I've been struggling with this, and the book I have (Node.js in Action) doesn't help me alot. But as I said, what I want is to display the .json info in the browser. Thx for reading

If I understand right, you may replace
document.getElementById("myDiv").innerHTML=xmlHttp.responseText;
with
var parsed = JSON.parse(xmlHttp.responseText);
var html = '';
for (var i = 0; i < parsed.length; i++) {
html += '<div>' + parsed[i] + '</div>';
}
document.getElementById("myDiv").innerHTML = html;
You may also try to replace
res.send(arr);
with
res.json(arr);
Update
Or maybe you just forgot to write this line in the beginning of server.js:
var readline = require('readline');

Related

Get Request for RESTful service not working

I'm trying to use a restful service to access data that is posted to a MongoDB cluster. My problem is that I can't even connect to the service, the get request doesn't seem to be working. Console.log("test")is not reached and I'm met with a blank console, so I don't think the readystate is changing.
I've done a ton of troubleshooting and found that the link works on its own (https://RESTfulServiceExample.[REPL.IT USERNAME].repl.co/items) and displays the data when pasted into the search bar. I've also tried changing browsers and even compared to my friend's code which works and STILL I can't even seem to connect.
I'm sure it's just some dumb little mistake but I'm completely at a loss here so any help is MUCH appreciated!
File with get request. I edited out the username. 'item' is the name of the MongoDB cluster.
<html>
<head>
<script type="text/javascript">
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && this.status == 200) {
console.log("test"); //NOT REACHED
var responseObj = JSON.parse
(xhttp.responseText);
};
}
//PROBLEM HERE
xhttp.open("GET", "https://RESTfulServiceExample.[REPL.IT USERNAME].repl.co/items", true);
xhttp.send();
</script>
<script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js">
</script></head>
<body>
<div id="chartContainer" style="height: 300px; width: 100%;">
</div>
</body>
</html>
RESTful Service:
Index.js: (edited out username and password of mongodb.
var express = require('express'); // control-shift-S to bring up shell in repl.it and npm
install express / other packages
var app = express();
var port = 5000; // the port is automatically routed by the repl.it domain
mongoose = require('mongoose');
Item = require('./model/model.js');
bodyParser = require('body-parser');
mongoose.Promise = global.Promise; // for asynchronous callbacks
mongoose.connect('mongodb+srv://[USERNAME]:[PASSWORD]#cluster0.thmkp.mongodb.net/Pokemon?
retryWrites=true&w=majority');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var routes = require('./routes/routes'); //importing route
routes(app); //register the route
app.listen(port);
Routes.js
'use strict';
module.exports = function(app) {
var itemList = require('../controllers/controller');
app.route('/items')
.get(itemList.list_items)
.post(itemList.create_item);
app.route('/items/:id')
.get(itemList.get_item)
.put(itemList.update_item)
.delete(itemList.delete_item);
};
Try to change
if (this.readyState == 4 && this.status == 200) {
// your code block
}

Return undefined answer from multer

I am using multer in my nodejs application for uploading files. And angularjs for the front end part. Once I click upload image, on the console I am getting undefined answer. Can any one help me to solve the problem.
Here I am pasting the code.
server.js
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var bodyParser = require('body-parser');
var path = require('path');
var fs = require('fs');
var spawn = require('child_process').spawn;
var multer = require('multer');
var storage = multer.diskStorage({
destination:function(req,file,cb){
cb(null,'public/upload/');
},
filename:function(req,file,cb){
cb(null,file.originalname);
}
});
var upload = multer({storage: storage});
app.set('views', __dirname + '/views');
app.use(bodyParser.json());
var urlencodedParser = bodyParser.urlencoded({ extended: true });
app.use(express.static('public'));
app.get('/',function(req,res){
res.render('index',{ title: 'Upload image' });
});
app.post('/loadImage',upload.any(),function(req, res) {
console.log(req.files);
console.log("Inside post");
});
http.listen(8080,'0.0.0.0',function(){
console.log('listening on 8080');
})
And here is my app.js angularjs code
var app = angular.module('app',['ui.router','ui.bootstrap','ngAnimate']);
$scope.img={};
app.controller('Ctrl',function ($scope,$http){
$scope.loadImage = function(){
$http.post('/loadImage',$scope.img).success(function(data){
console.log('Posted successfully');
}).error(function(data){
console.error('error');
})
};
And my HTML code:
<form ng-submit="loadImage()" enctype="multipart/form-data">
<input type="file" name="file" multiple />
<input type="submit" value="Upload Image" name="submit" />
</form>
On the console I am getting Undefined and Inside post. And on the browser console I am getting posted successfully Can any one please help me to solve this. Instead of undefined I should get loaded file information.
This how i used Multer to upload an image
var multer = require('multer');
exports.loadImage = function (req, res) {
var upload = multer({
inMemory: true,
limits: {fileSize: 1024 * 1024 }
}).single('newPicture');
upload(req, res, function (uploadError) {
if (uploadError) {
return res.status(400).send({ message: 'errorUploadingPicture' });
}
else {
var profileImage = 'No data uploaded';
// this is where the photo data is
if (req.file && req.file.buffer) {
profileImage = req.file.buffer;
}
return res.json(profileImage );
}
});
};
This is all assuming you are sending your file correct
try
var uploadType = upload.any()
and change
app.post('/loadImage',upload.any(),function(req, res) {
console.log(req.files);
console.log("Inside post");
});
to
app.post('/loadImage',uploadType,function(req, res) {
console.log(req.files);
console.log("Inside post");
});
if you are attempting to only get one file at a time then instead,
var uploadType = upload.single('file')
app.post('/loadImage',uploadType,function(req, res) {
console.log(req.files);
console.log("Inside post");
});

How to print external API on my server? (Take user ip address and show it on website)

I have just started using nodejs and koajs, and I would like to take the ip address from here: https://api.ipify.org?format=json and paste it on my site or set it as a header. Right now I have the following:
var koa = require('koa');
var app = koa();
var http = require('https');
var a = http.get("https://api.ipify.org?format=json",function(res) {
var data = "";
res.on("data", function (chunk) {
data += chunk;
});
res.on('end', function() {
par = JSON.parse(data);
console.log(par.ip);
});
});
app.listen(8888);
app.use(function *(){
this.response.set("userIp",par.ip);
this.body = "ipadress: "; //this doesn't see par.ip;
});
I know that I am probably doing something very wrong here but yea I am currently stuck because I have no idea how to take par.ip and assign it to this.body and set.
Would anyone be able to tell me how to achieve this or an alternative to the problem? Thanks in advance.
Assuming the response from api.ipify.org doesn't change.
var koa = require('koa');
var app = koa();
var http = require('https');
var a = http.get("https://api.ipify.org?format=json",function(res) {
var data = "";
res.on("data", function (chunk) {
data += chunk;
});
res.on('end', function() {
par = JSON.parse(data);
console.log(par.ip);
app.use(function *(){
this.response.set("userIp",par.ip);
this.body = "ipadress: "; //this doesn't see par.ip;
});
app.listen(8888);
});
});
Otherwise if the response from api.ipify.org constantly changes, you might to do the http request on every incoming request.

Stream video through socket to html5 video tag

Hello i`ve been trying to stream a webm video through a socket.io socket directly to the html5 video tag. The client and server code follows below:
Server:
(function() {
var Alert, Channel, Receiver, Takeover, express, pathLib;
pathLib = require("path");
fs = require("fs");
express = require("express");
module.exports = function(app, sockets) {
router = express.Router();
router.get("/clearAlerts", function(req, res) {
console.log("reached!");
return sockets.emit("alert-deleted");
});
router.get("/castVideo", function(req, res) {
//move this to a better place
console.log("reachedCastVideoss");
var readStream = fs.createReadStream(pathLib.join(__dirname + "/../../../public/elephants-dream.webm"));
readStream.addListener('data', function(data) {
console.log("cast-video emitted");
sockets.emit('cast-video', data);
});
});
return app.use('/custom/', router);
};
}).call(this);
Client:
var socket = io.connect('http://localhost:4994');
window.URL = window.URL || window.webkitURL;
window.MediaSource = window.MediaSource || window.WebKitMediaSource;
var mediaSource = new MediaSource();
var video = document.getElementById("video");
var queue = [];
var sourceBuffer;
var firstChunk = true;
video.src = window.URL.createObjectURL(mediaSource);
streamIt = function(e) {
video.pause();
mediaSource.addSourceBuffer('video/webm; codecs="vorbis,vp8"');
mediaSource.sourceBuffers[0].addEventListener('updateend', onBufferUpdated);
socket.on("cast-video", function(data) {
console.log("appending to buffer");
var uIntArray = new Uint8Array(data);
if (firstChunk) {
mediaSource.sourceBuffers[0].appendBuffer(uIntArray);
firstChunk = false;
}
queue.push(uIntArray);
if (queue.length === 33) {
//mediaSource.endOfStream();
}
});
var onBufferUpdated = function() {
if (queue.length) {
mediaSource.sourceBuffers[0].appendBuffer(queue.shift());
}
};
};
mediaSource.addEventListener('sourceopen', streamIt);
mediaSource.addEventListener('webkitsourceopen', streamIt);
When I try to run this code, It seems that the first chunk of the stream is appended
to the sourceBuffer, I can see the first frame(title and an url) of the video file im trying to play, but thats it. It seems that only the first call appendBuffer works. I read somewhere something about a required initialization segment for the video to play, but I also saw an working example that does not use this initialization segment, so im a little confuse.(link to the example)
Can anyone clarify if I really need this initial segment? If I do, how can I retrieve the byte range of this segment? Or if I dont need this segment, what is wrong in my code? Thank you.
Trying a little bit more today,Ive found that if I use the same file from http://html5-demos.appspot.com/static/media-source.html, this code actually works. When I try with the files from
http://www.webmfiles.org/demo-files, the code does not works. I have no idea why.

Cloud9 - Node.js fs can't open an html file

I do experiments with node.js and socket.io and it works fine locally.
I can read an html file and manage an interactive button for several users.
So i uploaded it on Cloud9 but i have an error ENOENT trying to find the html file.
It's in root (like in local) and the line is fs.readFile('ex.html' etc...
Here is the code of a test to open an html file and i have the enoent error on the console :
var http = require('http');
var fs = require('fs');
http.createServer(function(request, response) {
response.writeHead(200, {
'Content-Type': 'text/html'
});
fs.readFile('ex.html', function(err, data){
if(err) throw err;
response.end(data);
});
}).listen(process.env.PORT, process.env.IP);
Here is another program (full) that displays a blank page...
server :
var http = require('http');
var fs = require('fs');
// Creation du serveur
var app = http.createServer(function (req, res) {
// On lit notre fichier app.html
fs.readFile('app.html', 'utf-8', function(error, content) {
res.writeHead(200, {'Content-Type' : 'text/html'});
res.end(content);
});
});
var io = require("socket.io");
io = io.listen(app);
io.sockets.on('connection', function (socket) {
socket.on('joue', function () {
socket.broadcast.emit('joue2');
}); // joue
}); // connection
app.listen(process.env.PORT, process.env.IP);
client (app.html) :
<html><head> <title>Hello</title></head><body>
<button id="button">clic</button>
<div id="render">a</div>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io.connect();
var button = document.getElementById('button');
var render = document.getElementById('render');
button.addEventListener("click", clique, false);
function clique() {
socket.emit('joue');
}
socket.on('joue2', function () {
if (render.innerHTML == 'a') {
render.innerHTML = 'clic multi';
} else {
render.innerHTML = 'a';
}
});
</script></body></html>
I have installed socket.io on the server and all files are in the root of the folder node.js.
I already asked to Cloud9 but they said it works for them...
Sorry for my english and if im a beginner.
Thank you for your help :)
I guess your ex.html file is in node.js directory.
Try fs.readFile('node.js/ex.html', ...