My question can be pretty similar to others, but I already read a lot of answers, but I don't understand completely the details behind them.
I have to create a node.js REST API, but I don't took any lessons before. So i'm currently reading and trying tutorials to learn to create a simple node.js script.
I installed node.js, i created my script (it's just reading an input field), and when i click on a button, it's supposed to write the input in the console.
The tutorial needs only node.js, and use the .createserver. I understand that node.js is server side and can't be interpreted without it.
The tutorial asks to open the .html file in the browser, directly with the path. The html webpage shows up, but... When i'm pressing "ok", here's the errors :
*app.js:1 Uncaught ReferenceError: require is not defined
Access to XMLHttpRequest at 'file:///.../ApplicationAngular/nodeProject/app.html?name=' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
GET file:///.../ApplicationAngular/nodeProject/app.html?name= net::ERR_FAILED*
All the threads on StackOverflow explains that I need a third-party to run the HTML webpage. But on the tutorial, everything is working fine and never mentions the existance of Express, Cheerio, etc..
Here's the samples of code:
app.html
<input type="text" placeholder="Enter your name" id="name"/>
<input type="button" value="OK" onclick="valid()"/>
<div id="message"></div>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="app.js"></script>
<script>
function valid() {
$.get('', { name: $('#name').val() }, function(data) {
$('#message').html(data.message);
}, 'json');
}
</script>
app.js
var http = require('http');
var url = require('url');
var fs = require('fs');
var server = http.createServer(function (req, res) {
var url_parts = url.parse(req.url, true);
var name = url_parts.query.name;
if(name){
console.log('Nom: ' + name);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(JSON.stringify({message: 'Hello' + name + ' !'}));
} else {
console.log('No name !');
res.writeHead(200, {'Content-Type': 'text/plain'});
fs.readFile('app.html', function (err,data)
{
res.end(data);
});
}
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
Is the tutorial missing something? Do I have to install Express in order to view the page web?
Sorry again, english is not my native langage.
Thanks a lot for your answers.
With this line in your html
<script src="app.js"></script> <!-- wrong! -->
you try to run your nodejs program in your browser's javascript interpreter. You need to run it on your server instead. Your browser gacks on the require() operations because those are made to work in nodejs on your server.
Try removing the line from your html, and try doing something like this on your server's command line, then visiting http://localhost:1337 from your browser.
node app.js
The fact that browsers and nodejs support the same language is a bit confusing as you figure this all out. The language is the same but the two runtime environments are quite different. Be patient. You'll get it.
The app.js nodejs program you showed us should function correctly. In its if (name) branch it handles the request coming from the $.get() operation in the browser. In its else branch it delivers the html file to the browser.
And, it has to be said, doing more than just this kind of tutorial with nodejs alone -- without express or some other webserver framework -- gets to be a huge pain in the xxx neck, enough of a pain in the neck that you'll be tempted to develop your own framework.
Edit You have this line twice
res.writeHead(200, {'Content-Type': 'text/plain'}); /* wrong! */
Change both occurrences to
res.writeHead(200, {'Content-Type': 'text/html'});
The Content-Type: text/html header tells your browser to interpret your html file as html, not raw text.
Related
I am starting to learn html, css, and nodejs, and after writing a couple of very basic web pages I tried to run them on my computer, and view the page on my xbox-one with edge, but for each one (no matter how simple) it always says "Application is not supported, The webpage tried to start an application, such as an email program, that is not supported on xbox". I've tried with using the node html library as well as the express library, with and without html/css.
One code that would not work on the xbox:
server.js
var http = require('http');
var server = http.createServer(function (req, res) {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end("hello world!");
})
var PORT = 1021;
server.listen(PORT);
console.log("Server is running on 192.168.0.15:", PORT, '\n');
I can't find anything online, so any help would be greatly appreciated
Well after a lot of trial and error I found out that it was a very simple problem, I was putting 192.168.0.15:12345 into the address bar but it wanted http://192.168.0.15:1021.
I am using node.js to run the server. Always when I make a request to it actually there are occur two requests, one of which is an ordinary one, which was truly made and one is request/favicon.ico. So I tried to send favicon.ico back because I want it to appear in the top bar. But it just doesn`t appear there.
What am I doing wrong? Here is my code:
var http = require("http");
http.createServer(onRequest).listen(7777);
console.log("Server is running now.....");
function onRequest(request, response)
{
console.log("A user made a request" + request.url);
response.writeHead(200, {"Context-Type": "text/plain"});
response.write("Here is some data");
response.end();
}
And I put file favicon.ico into the same folder my server.js is.
This question:Set favicon in HTTP server? is not appropriate for me since the answer and code in answer, which were accepted, for it don`t work for me.
This should work
var http = require("http");
var fs = require("fs");
http.createServer(onRequest).listen(7777);
console.log("Server is running now.....");
function onRequest(request, response)
{
console.log("A user made a request" + request.url);
if (request.url === '/favicon.ico') {
var fileStream = fs.createReadStream("./favicon.ico");
return fileStream.pipe(response);
}
response.writeHead(200, {"Context-Type": "text/plain"});
response.write("Here is some data");
response.end();
}
But as you can see you have to create a special case for each url you want to handle. I recommend using a framework like express which will make things easy for you.
Also with framework you can have favicon in static directory so you won't have to explicitly read from file system on each request for static files.
You can do this by adding this line in your html page in head tag.
<link rel="icon" type="image/png" href=favicon.ico>
If you use http module directly then you will have to inspect the request object on every request and serve the favicon file yourself for all requests requesting favicons.
In your example, you will have to test the request object in the onRequest() function and serve a favicon for some requests, and your original stuff for the rest of the requests.
If you use Express or some other framework with Connect-compatible middleware, then you'll be able to use modules for that like this one:
https://www.npmjs.com/package/serve-favicon
If you want to use just the http module without Express or any other higher level framework, see this answer for examples on how to serve static images with http (and also with Express) that will help you with that:
How to serve an image using nodejs
I'm new to node.js and I cannot understand how the headers work. I'm trying to attach to my project fancybox in my index.html but it doesn't work. I'm using c9.io workspace so it looks like that <script src="http://space.......c9.io/jquery.fancybox-1.3.4.js"></script>
I still get the same error in console: socket io Resource interpreted as Script but transferred with MIME type text/plain:
Please, is there anyone who can explain me this as simple as possible ?
my js file
var http = require("http"),
express = require('express'),
app = express(),
server = app.listen(process.env.PORT),
io = require('socket.io').listen(server)
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
io.sockets.on('connection', function (socket) {
});
I think the solution to your problem is a little type="text/javascript" that you should add to your script tag, but here's a low down on mimetypes:
Here's some text about setting headers when using raw Nodejs.
And here's the same thing when using Express.
And here's mimetypes on wikipedia.
I'm not an expert, but as I understand it, every file or chuck of info sent from server to client (browser, mostly) comes with this mimetype that basically tells the browser how to deal with the file / chuck.. Your browser is smart enough to handle that file correctly even though he received no headers + he is smart enough to notify you that other browsers might not be that smart.
This is how I'd write it:
app.get('/',function(request,response){
response.set('Content-Type', 'text/html'); // 'text/html' => mime type
response.sendfile(__dirname + 'index.html')
}
Lots of mimetypes are listed here. But I think you can just google something like "{file extension} mime type" and google will serve you well.
Alternatively, you can use this little package to change response.set('Content-Type', 'text/html') into response.set('Content-Type', mime.lookup(x)); - x being a string such as 'kuku.mpeg' and mime will return the currect mimetype. I use it to resolve plugins that have many subfolders with different filetypes on each one.
A HTTP header is field that contains information about a HTTP request or response. It helps the server or client identify what to do with the data, whether it be what type of data to accept, how big the request or response should be, the origin of the request, to cache data or not, etc.
In HTTP, MIME headers tell the client or server what the type of data is going to be sent or received. The error message you received probably means that the browser thought it was going to receive MIME type text/javascript but received text/plain instead.
Resource interpreted as script but transferred with MIME type text/plain
To fix this problem, specify the content type when sending the script file:
app.get('/script.js', function(req, res) {
res.set('Content-Type', 'text/javascript');
res.sendfile('./script.js');
});
Note that HTTP headers are not specific to Node.js, but are part of the HTTP protocol.
I use node js without frameworks etc. and I have problem, I don't understand how set "start html page" for my first request to server.
I tried do it like this
var server = new http.Server();
server.listen(1137, '127.0.0.1');
server.on('request', function(req, res) {
fs.readFile('../public/index.html', function (err, html) {
if (err) {
throw err;
} else {
res.write(html);
res.end();
}
});
});
When I do request to 127.0.0.1:1137 - I got html in browser, but links to CSS/JS files isn't correct and how I can this to fix I don't know :(
I want get the html page ../public/index.html in browser when I will do first request to my server.
my server location
project/server/server.js
my html-page location
project/public/index.html
Your page includes references to images and stylesheets, which you said don't work.
Well, you are responding to every single HTTP request with the contents of the specified HTML page.
When the browser parses the HTML, it will see the image and stylesheet links and issue HTTP requests to those URL's. But those URL's don't respond with images or stylesheets. They respond with HTML.
GET /index.html
yields
<html>
<head>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<img src="someimage.png">
</body>
</html>
The browser then requests
GET /styles.css
yields
<html>
...
</html>
The browser then requests
GET /someimage.png
yields
<html>
...
</html>
You need to make the response conditional based on the request. To prevent disclosure of information, like #minitech mentioned, you need to be careful not to blindly concatenate the paths. Then you have to worry about MIME types.
You're really best off using a framework like express.
You will need to return different files, depending on the path that was requested.
On the 'request' handler you are getting a ClientRequest object, which has a path property. Use this information to return the correct files (index.html, the CSS or JS files...). An example request callback could be:
function onRequest(req, res) {
var path = req.path;
fs.readFile('../public' + path, function(err, contents) {
if (err) {
res.writeHead(500);
res.end(err);
return;
}
res.end(contents);
});
}
This is still very basic, you will probably want to handle non-existent files with a 404 result code, return the correct Content-Type headers the different file kinds (text/html, text/css, etc).
Update: as minitech recommends, the path should be checked for ../, which would go up the filesystem and access sensitive files.
Hope this helps.
This is really weird problem. I just installed Node.JS on my system (Fedora).
I have three files in /var/www/mirror/:
server.js
client.js
index.html
File server.js is the one I call via CLI: node server.js.
It, basically, returns index.html.
var
http = require('http'),
io = require('socket.io'),
fs = require('fs');
http.createServer(function(request, response) {
fs.readFile(__dirname + '/index.html', function(error, data) {
if (error) {
result.writeHead(500);
console.log('Error: Could not read index.html.');
}
response.writeHead(200, {'Content-Type': 'text/html'});
response.end(data);
});
}).listen(1337, '127.0.0.1');
console.log('Server is running.');
All works as expected and no errors are thrown anywhere.
In index.html I have simple HTML5 structure (nothing unnecessary, really!) and <script /> that points to, already mentioned, client.js.
That line of code looks like this (Ctrl + U; from browser):
<script src="client.js"></script>
By moving cursor on client.js, I got actual location: http://127.0.0.1:1337/client.js.
Seems correct, right?
The problem:
By opening that link it opens wanted file, but the content is as server.js should return.
This disallows me from including any internal scripts and style-sheets!
I guess that anything that goes via http://127.0.0.1:1337/ (also http://127.0.0.1:1337/client.js, http://127.0.0.1:1337/a/b/c etc.) is handled via server.js - and server.js returns index.html (see above).
How can I fix it? Thanks in any advice!
Look at the req.url to tell you the url that the user is requesting. From there, you have to have some code decide whether to serve index.html or client.js.
Also, since I'm guessing index.html isn't changing very frequently, you should probably just read it once, and store the buffer in a variable, rather than reading it on every request.
There are some modules that make serving static files a bit easier. Check out filed for a pretty nice standalone static file