I'm very new to node.js so I apologize if this is a poor question. I have a simple HTTP server here:
var http = require('http');
http.createServer(function (request, response){
response.writeHead(200, {"Content-Type":"text/html"});
// response.write("<html><head><script type = 'text/javascript'>alert('hello');</script></head></html>");
response.write("<html><head><script type = 'text/javascript' src = 'alerter.js'></script></head></html>");
response.end();
}).listen(8000);
console.log("Server has started.");
alerter.js contains the one line:
alert("hello");
Why does using the commented-out line properly cause an alert, but calling alerter.js does nothing?
Your problem, as Paul and Timothy pointed out, is that when the browser gets your html with an external reference, it goes back to the server and asks it for alerter.js, expecting to have the script delivered to it. However, your server always sends out the same thing regardless of what the request asks for, so the browser never gets the script.
You need to change your server to, at the very least, handle a request for alerter.js. Realistically, I'd use something like Connect's static file handler to do that; put all the assets like scripts, stylesheets and images in a directory (usually called "public") and tell the static handler to serve them from there.
You are missing a ' to end the type attribute.
Related
I moved my website and I have a QR code (which is printed in public and can't be easily replaced) that points to a specific file on my old website that has now been moved. Currently, the URL just points to a "Not found" page on my new website. I try to use javascript in the header to catch the URL and forward it to the right URL as following:
<script type="text/javascript">
if(window.location.href === "https://www.website.com/multimedia/hoerproben/1.mp3")
{
window.location.href = "https://www.webseite.com/app/download/10079133850/1.mp3";
}
</script>
But it doesn't work. Any hints what I am doing wrong?
when you open an url, the browser makes an http request to your server for that particular resource (in your example, an mp3 file).
JavaScript is not involved at all (actually, there are so called "service workers", but they are not what you're looking for, they are meant to do caching, not redirecting). The browser does not know that your JavaScript code exists and would not execute it.
What you should do is route redirecting from server, so when the browser asks from /oldlocation/file.mp3, instead the server answers with /newlocation/file.mp3
This could be in some different way according to your server. If you have no control on how your server works, what you're asking is simply not possibile.
It won't work unless you place that code in the "Not found" page that gets served. If your URL pointed to an HTML file, you could have just placed one to do the redirect. For media files you would have to configure your server to serve an HTML file instead. Don't worry about the extension, it's the Content-Type header that determines the type of the file served. Doing this, however, is not good practice because your server would still be returning a 200 response code.
It's good practice to return 301 Moved Permanently as 101arrowz pointed out in the comments. How that can be accomplished will depend on what server you're using.
Here's how that would have been accomplished with express.js:
app.get('/multimedia/hoerproben/1.mp3', function(req, res) {
res.redirect('/app/download/10079133850/1.mp3');
});
I have already added the codes for serving an image on my node server but it seems to not serve images in the HTML when connecting to Node. I have also external CSS and JS that are being served correctly. Here is the fragment of my code in Node (See below). Thank you in advance!
var server = http.createServer(function(req, res) {
var pathname = url.parse(req.url).pathname;
var ext = path.extname(pathname);
var handler = handlers[req.url];
if(ext) {
if(ext === ".css"){
res.writeHead(200, { "Content-Type" : "text/css" });
}
else if(ext === ".js") {
res.writeHead(200, { "Content-Type" : "text/javascript" });
}
else if(ext === ".jpg") {
res.writeHead(200, { "Content-Type" : "image/jpg" });
}
res.write(fs.readFileSync(__dirname + pathname, "utf8"));
res.end();
}
else if(handler) {
handler(req, res);
}
else {
res.writeHead(404, { "Content-type" : "text/plain" });
res.end();
}
});
server.listen(80);
I've seen a lot of questions like this on Stack Overflow when someone tries to implement their own static file server instead of using Express or something that works, and fails to make it work. If you can implement your own static file server then do it. If you can't, then it should be a sign that maybe it's not a good idea. Update: See below for solutions without Express.
Problems
Just by glancing at your code code I already see several serious problems with it, including:
Your code is insecure - it allows anyone to get any file on your system.
Your code is blocking - it will grind to a halt as soon as you get any concurrent connections.
Your code doesn't work for binary files - only for text files, and only those with UTF-8 encoding
Your code doesn't work for uppercase filenames, .jpeg extension etc.
Your code doesn't serve HTML files correctly
Your code crashes when files don't exist instead of responding with proper code
Solution
Anyone who answers a question like this has two options: either put a lot of effort and time into fixing every one of the problems mentioned above (which rarely happens because it is not a trivial task and that's why all you see are comments mentioning one or two of those problems instead of answers) or you can explain how the task should be done properly instead of adding countless fixes to something that was not a good idea in the first place.
That having been said, what you can do to achieve your goal here in a secure and performant way is to put your static files (HTML, CSS, images etc.) into a directory, e.g. called html and use Express (or some other frameworks, see below) with a simple code like this:
var path = require('path');
var express = require('express');
var app = express();
var htmlPath = path.join(__dirname, 'html');
app.use(express.static(htmlPath));
var server = app.listen(80, function () {
console.log('listening on port', server.address().port);
});
See the full example with explanation on GitHub:
https://github.com/rsp/node-express-static-example
I put this example on GitHub because there are a lot of questions on Stack Overflow related to problems that people have with serving static files in Node. It's open-source, you can adapt it to your own needs and use in your code.
For more info on Express, see:
http://expressjs.com/en/4x/api.html
Other options
Other frameworks that you can use to serve static files include:
koa, Restify, Hapi, Sails, LoopBack and more.
Without a framework
If you still think that you don't want to use a high-level framework that does the job correctly and you want to roll your own solution, maybe for educational purposes, then see this answer:
How to serve an image using nodejs
It explains how to serve static images with:
express.static (express built-in middleware, like in this answer)
express (express but without express.static)
connect (one level below than express)
http (using Node's http module)
net (not even using http module)
All of the examples posted are tested and work on Node versions 4, 5, 6 and 7.
Other related answers:
How to serve an image using nodejs
Failed to load resource from same directory when redirecting Javascript
onload js call not working with node
Sending whole folder content to client with express
Loading partials fails on the server JS
I'm hosting a webpage on github (flickrTest.html) and I'm trying to check the existence of a folder in the same directory as the webpage. The hosted folder looks like this:
http://imgur.com/a/pZWoH
I try to use an ajax call like this:
$.ajax({
url: 'mapData',
error: function() {
//Ddirectory doesn't exist
console.log("ERROR: expected directory named 'mapData'. Exiting...");
return
},
success: function() {
//Directory does exist
console.log("mapData exists..");
...
but I'm getting a mixed-content error because this call is considered http and the site my webpage is being hosted on is https. Somehow I'm able to access mapData's JSON files if I include the absolute path. Is there a way to check for the existence of a folder over https?
First, there is a fundamental problem with your approach. As others have stated in comments, you cannot check if a folder has contents (or exists) with a simple http (or https) web request since the web server will expect to respond with HTML that can be presented as information for a user's browser. You can create a handler or script that will process a directory request and map that functionality using something like a .htaccess rule or other rewrite system depending on what platform you are on. The reason why I've identified this as a "problem" and have not gone as far to say it's impossible, is because you can (as it appears you are attempting) parse that response into something usable. That said, I think it's beside the point and not the nature of the error you are actually getting.
The error you are experiencing is coming from loading the current page you are on in HTTPS and the ajax request you are making is over HTTP (as indicated by the error message). This message can be misleading in your case since it's not that the request URL has not been identified as HTTPS, it's because the browser doesn't trust that the URL is a Web request to either a file or a folder. You can correct this by simply adding a trailing slash to the folder:
$.ajax({
url: 'mapData/',
error: function() {
//Ddirectory doesn't exist
console.log("ERROR: expected directory named 'mapData'. Exiting...");
return
},
success: function() {
//Directory does exist
console.log("mapData exists..");
...
You have now resolved the issue of completing the web request, but you are faced with a problem that is mentioned in the first part. The server will return a 404 error because that is how github.io is configured to respond to empty (or non-existent) directory requests. You will need some type of server-side handler to process this request, or you will need to come up with something else creative such as putting an index.html in that folder so that your JavaScript can parse the result. For instance, you could drop an index.html in the folder and if the server returns 200, then you know the folder exists, but if it returns 404 then you can assume the folder does not exist.
In case it's not already known, web servers are designed to make it so that a browser is limited in reverse-engineering it's content. While servers can be configured to return directory contents, by default, most are going to protect folders so that remote users cannot browse the server without some type of elevated permissions/authentication. Essentially, the reason why this requires a a more customized server-side approach is not because there is something wrong with the front-end code, it's because the web server is designed to not allow this type of thing without the server being configured to allow it due to security.
i'm reading the book 'Node.js for PHP Developers'. I have created a NodeJS Web Server and it receives requests and gives response too. But whenever I access a PHP file to reroute it to a JS file (requirement it is), my browser automatically downloads the PHP file.
Here's my JS code, according to which it also downloads JS files(e.g. when I access localhost:1337/first.njs)
var http = require('http');
var url = require('url');
var file = require('./first.njs');
http.createServer(function(req, res) {
if(url.parse(req.url).pathname == 'first.php')
file.serve(req, res);
else
res.end('The file doesn\'t exist');
}).listen(1337, '127.0.0.1');
console.log('Server is running on 1337');
And here's my PHP file if it matters
<?php
echo "ASD";
?>
I know it feels like a really dumb question, but I can't figure out why that happens.
Browsers tested: Chrome and Firefox.
UPDATE
Couldn't figure out the exact problem neither could replicate the problem - but this is my latest code if anyone wants to reroute a requested PHP file to a JS file and serve it(the JS file)
var http = require('http');
var url = require('url');
var file = require('./first.njs');
http.createServer(function(req, res) {
if(url.parse(req.url).pathname == '/first.php')
file.serve(req, res);
else
res.end('File not found');
}).listen(1337, '127.0.0.1');
console.log('Server is running on 1337');
If you want to check if a PHP page can be rendered without actually rendering it to the page you can use an ajax request in JavaScript/jQuery.
$.ajax({
type: "POST",
url: 'YOUR PHP FILE PATH',
success: function (dataCheck) {
// file was accessed
}
});
Inside your success function you can output that the PHP file was successfully accessed.
Once you get a better handle on node, you'll probably want to use expressjs, take a look at expressjs routing.
app.get('/first.php', function(req, res){
res.send('You accessed first.php!');
});
If you then wanted to display the php, you could use php-node to render php in node.js.
It seems that you don't have Apache (or some other server) or PHP configured. The request has to go to the PHP script first. So you would have to hit localhost:80/file.php and then in the PHP script redirect to localhost:1337/file.js.
A better suggestion for what you want to do is actually reverse proxy from Apache to Node.js and then have Node.js read the path.
I've got a very simple html5 game on one side. Opening the game's html file directly with my browser makes the game work just fine. On the other side, I have an html sever made with node.js that can serve html text normally (tags like < /br> < p> and so on).
But when I tell the server to display my game as html text priting the whole html file, the canvas fails to render (although the title does). So now I'm kind of lost on what's happening and why I'm not able to link those two things together. Here's a simplified version of my server's code:
var http = require('http');
var fs = require('fs');
var index = fs.readFileSync('index.html');
http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(index);
res.end()
}).listen(7777);
So, what am I doing wrong here? Should this work normally? Am I missing something?
It seems just as if the javascript was sent as plain text and the code was never actually executed.
Your server serves only the index.html so if that page depends on any other resources it will fail to work as requests to CSS and JS files will fail. Try out e.g. this:
$ npm -g install simplehttpserver
$ simplehttpserver /path/to/your/folder
Then go with browser to
http://localhost:8000/index.html