I have an application, which streams an MP3 using Node.JS. Currently this is done through the following post route...
app.post('/item/listen',routes.streamFile)
...
exports.streamFile = function(req, res){
console.log("The name is "+ req.param('name'))
playlistProvider.streamFile(res, req.param('name'))
}
...
PlaylistProvider.prototype.streamFile = function(res, filename){
res.contentType("audio/mpeg3");
var readstream = gfs.createReadStream(filename, {
"content_type": "audio/mpeg3",
"metadata":{
"author": "Jackie"
},
"chunk_size": 1024*4 });
console.log("!")
readstream.pipe(res);
}
Is there anyone that can help me read this on the client side? I would like to use either JPlayer or HTML5, but am open to other options.
So the real problem here was, we are "requesting a file" so this would be better as a GET request. In order to accomplish this, I used the express "RESTful" syntax '/item/listen/:name'. This then allows you to use the JPlayer the way specified in the links provided by the previous poster.
I'm assuming you didn't bother visiting their site because had you done so, you would have seen several examples of how to achieve this using HTML5/JPlayer. The following is a bare-bones example provided by their online developer's documentation:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
<script type="text/javascript" src="/js/jquery.jplayer.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#jquery_jplayer_1").jPlayer({
ready: function() {
$(this).jPlayer("setMedia", {
mp3: "http://www.jplayer.org/audio/mp3/Miaow-snip-Stirring-of-a-fool.mp3"
}).jPlayer("play");
var click = document.ontouchstart === undefined ? 'click' : 'touchstart';
var kickoff = function () {
$("#jquery_jplayer_1").jPlayer("play");
document.documentElement.removeEventListener(click, kickoff, true);
};
document.documentElement.addEventListener(click, kickoff, true);
},
loop: true,
swfPath: "/js"
});
});
</script>
</head>
<body>
<div id="jquery_jplayer_1"></div>
</body>
</html>
Related
I have an express app, in which I have the following code:
app.get('*', (req, res) => {
res.send('404', {
title: 404,
name: 'James Olaleye',
errorMessage: 'Page not found',
});
});
However, My IDE is warning about this message:
express deprecated res.send(status, body): Use
res.status(status).send(body) instead
And with the above code, My Browser is returning the following payload as a JSON object:
{
"title": 404,
"name": "James Olaleye",
"errorMessage": "Page not found"
}
What I want, is to display a 404 Not found page to the user, how can this be achived?
You have two seperate problem
1: you are using an old way to response to the request insted use this res.status(STATUS_CODE).send(BODY)
2: you are sending a json yet you want to display a 404 page in this case you need to send a html template
so your code should look like this
app.get('*', (req, res) => {
res.status(404).send("<div>404 Not Found</div>");
});
I updated your question a bit to make it clearer for future references.
the method res.send is deprecated, among other things because it's usages is too ambiguous. A server response, can be a lot of things, it can be a page, it can be a file, and it can be a simple JSON object (which you have here).
In your case, when you run res.send(404,{ /*...*/ }), the express app assumes you want to send a JSON object, so it does just that.
There are multiple possible ways, to achieve what you want, but I will stick to the most simple solution.
If you want to display an HTML page, in the most simplest form, you can actually just change your piece of code to do this instead:
app.status(404).send(`<h1>Page not found</h1>`)
This will essentially, show a page, instead of a JSON object.
You can even define the whole HTML file if you like:
app.status(404).send(
`
<html>
<!DOCTYPE html>
<head>
<title>404</title>
</head>
<body>
<h1>James Olaleye</h1>
<h1>Page Not Found</h1>
</body>
</html>
`
)
This would be the fastest way to achieve what you want.
A step further, would be to create an HTML file some where in your app, and to send the HTML file instead.
If your source code looks like this:
/
src/
index.js
htmls/
404.html
<!-- htmls/404.html -->
<html>
<!DOCTYPE html>
<head>
<title>404</title>
</head>
<body>
<h1>James Olaleye</h1>
<h1>Page Not Found</h1>
</body>
</html>
// src/index.js
const express = require('express');
const app = express();
const path = require('path');
const PORT = 3000;
app.get('/', function(req, res) {
const options = {
root: path.join(__dirname, '..', 'htmls')
};
res.sendFile('404.html', options, function (err) {
if (err) {
next(err);
} else {
console.log('Sent:', fileName);
}
});
});
This would allow you to have multiple HTML files which you can send around.
There are like I stated, other options as well, but that would make this answer way too long and out of scope. If you are interested, you can research Using template engines with Express and start with the following link.
Happy coding :)
I am using a sample project from auth0.com to customize the login page for my app and enable social media login. However I encounter some problem when I try to deploy it to bluemix.
The video tutorial I follow is https://www.youtube.com/watch?v=sHhNoV-sS_I&t=559s
however the sample project is a little bit different from the one in video. It required the command "npm serve" to run it. When I push my project using cf push it shows noappdecked. How can I deploy my project to bluemix?
the app.js code and html code is like
<!DOCTYPE html>
<html>
<head>
<title>Auth0-VanillaJS</title>
<meta charset="utf-8">
<!-- Auth0 lock script -->
<script src="//cdn.auth0.com/js/lock/10.3.0/lock.min.js"></script>
<script src="auth0-variables.js"></script>
<script src="app.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<img alt="avatar" id="avatar" style="display:none;">
<p>Welcome <span id="nickname"></span></p>
<button type="submit" id="btn-login">Sign In</button>
<button type="submit" id="btn-logout" style="display:none;">Sign Out</button>
</body>
window.addEventListener('load', function() {
var lock = new Auth0Lock(AUTH0_CLIENT_ID, AUTH0_DOMAIN);
// buttons
var btn_login = document.getElementById('btn-login');
var btn_logout = document.getElementById('btn-logout');
btn_login.addEventListener('click', function() {
lock.show();
});
btn_logout.addEventListener('click', function() {
logout();
});
lock.on("authenticated", function(authResult) {
lock.getProfile(authResult.idToken, function(error, profile) {
if (error) {
// Handle error
return;
}
localStorage.setItem('id_token', authResult.idToken);
// Display user information
show_profile_info(profile);
});
});
//retrieve the profile:
var retrieve_profile = function() {
var id_token = localStorage.getItem('id_token');
if (id_token) {
lock.getProfile(id_token, function (err, profile) {
if (err) {
return alert('There was an error getting the profile: ' + err.message);
}
// Display user information
show_profile_info(profile);
});
}
};
var show_profile_info = function(profile) {
var avatar = document.getElementById('avatar');
document.getElementById('nickname').textContent = profile.nickname;
btn_login.style.display = "none";
avatar.src = profile.picture;
avatar.style.display = "block";
btn_logout.style.display = "block";
};
var logout = function() {
localStorage.removeItem('id_token');
window.location.href = "/";
};
retrieve_profile();
});
You would use the package.json method documented at https://console.ng.bluemix.net/docs/runtimes/nodejs/index.html#nodejs_runtime , first to declare the serve package as one of your dependencies, then to indicate what the scripts.start script should do (which is run npm serve). You can use npm init (https://docs.npmjs.com/cli/init) to create a starting package.json file if you don't already have one.
I am trying to load local javascripts with jsdom.
Now I am wondering how I can make jsdom loading the javascripts from "__dirname/../public".
Can someone help me?
My current code is:
var fs = require('fs');
var jsdom = require('jsdom');
jsdom.defaultDocumentFeatures = {
FetchExternalResources: ["script"],
ProcessExternalResources: ["script"],
MutationEvents : '2.0',
QuerySelector : false
};
exports.test = function(req, res) {
var html = fs.readFileSync(__dirname+'/../public/html/lame.html');
var document = jsdom.jsdom(html, null, {documentRoot: __dirname+'/../public/'});
var window = document.createWindow();
window.addEventListener('load', function () {
//window.$('script').remove();
//window.$('[id]').removeAttr('id');
res.send(window.document.innerHTML);
window.close();
});
}
The simple HTML page is:
<html>
<head>
<title id="title">bum</title>
<script type="text/javascript" src="/javascripts/jquery.min.js"></script>
<script type="text/javascript" src="/javascripts/stuff.js"></script>
</head>
<body>
<h1>hello world</h1>
<h2 id="bam">XXX</h2>
</body>
</html>
I've run into the same issue and got it to work. Try these, in order:
documentRoot is not documented. The option which is documented is url. So replace documentRoot with url.
If the above is not enough, then add a base element. I've set my templates like this:
<head>
<base href="#BASE#"></base>
<!-- ... -->
</head>
where #BASE# is replaced with the same value as the one passed to url.
The solutions above are extracted from actual code in use in a test suite.
Following are the structure of my application
Inside prototype.js file i have following code:
(function(exports) {
exports.foo = function() {
return 'bar';
};
})((typeof process === 'undefined' || !process.versions) ? window.common = window.common || {} : exports);
app.js contains
var express = require('express'),app = express(),server = require('http').createServer(app),io = require('socket.io').listen(server),port = 3000,path = require('path');
var common = require('common/prototype');
console.log(common.foo());
// listening to port...
server.listen(port);
//Object to save clients data
var users = [];
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function (req, res) {
res.sendfile('/public/index.html');
});
index.html contains
<!doctype html>
<html lang="en">
<head>
<title>Socket.io Demo</title>
</head>
<body>
<script src="/socket.io/socket.io.js"></script>
<script src="/common/prototype.js"></script>
<script>
alert(window.common.foo()); //This line will gives me an error TypeError: window.common is undefined
</script>
</body>
</html>
Now i would like to print
Hello, I am bar from server and client as well.
Now i am able to print from server side using following line
var common = require('common/prototype');
console.log(common.foo());
But could not able to show alert on client side. could you please help me to find the root cause for the issue.
The root cause is that when you do <script src="/common/prototype.js"></script> in your HTML the file won't be fetched because the Express static middleware is only looking for files under your public folder.
A quick way to test this is to copy your prototype.js to your javascript folder inside public. Then update your script tag to reference the file as follows <script src="/javascripts/prototype.js"></script>
The thing to remember is that the JavaScript files that live under node_modules are not automatically available to the browser.
In the express server I have this.
app.dynamicHelpers({
dynamicValue: function(req, res) {
console.log("returning a new value");
return parseInt(Math.random() * 100);
}
});
In the client I have this.
setInterval(function() {
alert(<%= dynamicValue %>);
}
,1000);
So every second, a new number should be shown.
But that's not what happens. When the page loads a new number is generated, but the number that the client sees is always the same unless the page is reloaded.
How can this be changed to do what it's supposed to?
You are mixing server code and client code up here. The statement <%= dynamicValue %> renders the value into a script on the page:
setInterval(function() {
alert(<%= dynamicValue %>);
}
,1000);
becomes
setInterval(function() {
alert(82.9090561);
}
,1000);
This script is later interpreted by the browser. The browser has no access to the "server script code base".
In order to make this work on the client, you need to include the particular script that creates a random number on the page:
<script type="text/javascript" src="dynamic.js" />
<script type="text/javascript">
setInterval(function() {
alert(smth.dynamicValue());
}
,1000);
</script>