jQuery .load() from local httpd (node) - node.js

Node.js server
var http = require("http");
http.createServer(function(request,response){
console.log("client connected");
response.writeHeader(200,{"Content-type": "text/html"});
response.write("Hello ;-)");
response.end();
}).listen(9090);
I try to load the server output into a div with the ID "myDisplayField":
$("#myDisplayField").load("http://localhost:9090");
(The HTML-File lies on my local httpd)
The issu I'm having with that is that the node server may show that he got a request from ajax ("client connected"), but "Hello ;-)"/the site content doesn't get loaded into #myDisplayField as expteced.
If I set up a webserver like Apache and put a index.html with "Hello ;-)" in htdocs, the whole thing works just fine.
What am I doing wrong?

I just tried your code, and navigating to localhost:9090 displays the 'hello' body as expected.
It may be that jquery's load() method looks for other data - for example, content-type in the header - that your very simple response doesn't provide. Instead of building every http response individually, you should use a higher-level server like express:
var express = require('express');
var app = express();
app.use(function(req, res, next) {
res.send('Hello');
});
app.listen(9090);

Related

cannot get POST request on express

I can't get any POST requests with the express framework.
This is my code
var express = require("express");
var app = express();
app.set("view engine","ejs")
app.get("/", function(req, res){
res.render("home");
});
app.post("/addfriend", function(req, res){
res.send("you have reached the post route succesfully");
});
app.get("/friends", function(req, res){
var friends =["lara","tommy","miranda","faith","locas"];
res.render("friends",{friends : friends});
});
app.listen(3000, function(){
console.log("server is listening on port 3000");
});
any suggestion please.
Few observations.
1)You are missing body parser for your app.js ( if in future you want to read form data).
just add this to your app,js
const app = express();
app.use(bodyParser.json());
Wherever you are using trying to send post request for example a HTML form or a button does it have correct route, it should match with this post route /addfriend.
Browser always send get request to server from browser, to specifically send post request use postman, curl or a HTML form.
If you are using postman try this https://learning.postman.com/docs/sending-requests/requests/#sending-body-data
For the difference between get and post follow this
Edit :-
Http post request means :- "The HTTP POST method sends data to the server. The type of the body of the request is indicated by the Content-Type header."
get request :- "The HTTP GET method requests a representation of the specified resource. Requests using GET should only be used to request data (they shouldn't include data)."

How to return a static xml file from nodejs server

I am integrating a 3rd party template which has a slideshow written using Mootools. The nodejs is configured with express and ejs
The data for the slideshow comes from a few xml files. For example data.xml. I placed the data.xml in public folder and added the following code to server.js (the main file)
app.use(express.static(__dirname + '/public'));
app.post('/data.xml', function(req, res){
res.contentType('application/xml');
res.sendFile('/data.xml');
});
Unfortunately this does not seems to work. I can see the file if I type the url
http://localhost:8080/data.xml
But the response I see in firebug is
" Cannot POST /data.xml "
I am assuming Mootools is trying to access the file using some POST method. Any suggestions for this problem?
when you are sending the file with sendFile() you need to point to the absolute address check this. note that I have the data.xml in the main folder.
you can access the file with localhost:8080/data (not localhost:8080/data.xml) and also as this is a post, you cannot access it through browser. use postman instead. or if you need it to be accessible on browser you need to change the protocol to get.
var express = require('express');
var path = require('path');
var app = express();
// you don't need this line!
// app.use(express.static(path.join(__dirname)));
app.post('/data', function(req, res){
res.contentType('application/xml');
res.sendFile(path.join(__dirname , 'data.xml'));
});
var server = app.listen(8080, () => {
console.log('Started listening on 8080');
});

Manually injecting express app via `http.createServer` proxy

I am currently authoring a component for a users sites which adds a number of resources to their server. For my part, I am wanting to use express, but the user could be using express themselves or some other web framework.
Because I want this to just work out of the box, I was attempting to setup my express pipeline via proxying http.createServer. Injecting the pipeline this way seems to work reasonably well in cases where I handle the request, but it fails in cases where I let it fall through and execute the users callback (specifically, it says that the response headers have been sent already).
Here is the sample I am working on. Any ideas?
var http = require('http');
var express = require('express');
var setupProxy = function setupProxy() {
var app = buildApp();
var oldCreateServer = http.createServer;
http.createServer = function(callback) {
return oldCreateServer(function(req, res) {n
app.apply(this, arguments);
if (!res.finished) {
callback.apply(this, arguments);
}
});
};
};
var buildApp = function buildApp() {
var app = express();
app.use('/test', function(req, res) {
res.send('Hello World');
});
return app;
};
I suspect your express handling creates a default 404 response when it doesn't match any of your routes. So, that would be the cause of the headers already sent issue when you are not handling it, but trying to pass it on.
So, I think you need your own 404 handler that writes nothing to the request (e.g. does nothing), but keeps Express from handling it.
Or, another possibility would be to call the user's server callback from your express 404 handler and not elsewhere.

Cross-domain POST request in Node.JS with preflight?

I have just started with Node.
I am trying to get cross-domain form data from an HTML form to parse in a Node.js server. I have been able to do this with simple POST data, not with POST requests that require preflight.
I am running the Node code on cloud9 app servers. I am also using the Cors module to handle the requests. This module works well with simple requests (test here to see a simple request work), however with requests that require preflight I get this result from the Chrome inspector console.
XMLHttpRequest cannot load https://nms-motaheri-1.c9.io:8080/mail.
The request was redirected to 'https://c9.io:8080/api/nc/auth?.....SHORTENED',
which is disallowed for cross-origin requests that require preflight.
Here is my server.js code:
// Define dependencies
var express = require('express')
, cors = require('cors')
, app = express()
, parse_post = require("parse-post");
// Core module config
var corsOptions = {
origin: '*',
preflightContinue: true // <- I am assuming this is correct
};
app.use(cors(corsOptions));
// Respond to option request with HTTP 200
// ?? Why is this not answering my OPTION requests sufficiently ??
app.options('*',function(req,res){
res.send(200);
});
// Give a hello world response to all GET requests
app.get('/',function(req,res){
res.sendFile(__dirname + '/index.html');
});
// Handle all POST requests to /mail
app.post('/mail', parse_post(function(req, res) {
console.log(req.body);
res.json({msg: 'This is CORS-enabled for all origins!'});
})
);
// Listen on default Cloud9 port which is 8080 in this case
app.listen(process.env.PORT, function(){
console.log('CORS-enabled web server listening on port ' + process.env.PORT);
});
Why is this happening and how can I satisfactorily answer the OPTION request for my POST with pre-flight?
Here is the post request and response in Chrome dev tools:
Turns out that part of the problem was that the cloud9 server was set to private making these requests all redirect.
After making the server public, the redirections stopped. However, I received an error that the Node.js server did not have any Access-Control-Allow-Origin headers to allow requests from my cross origin domain. I noticed that "simple" with-out preflight requests would go through. So instead of trying to understand why it was not accepting my allow-all-origin-configuration on the Node.js side I decided to serialized the POST data to get rid of the preflight requirement and changed the data type in my angular request to plain text.
To get rid of preflight, first get rid of any POST header configuration (cache, etc), make sure your request Content-Type is plain text and make sure your actual content is plain text too. So if it is in JSON serialize it in jQuery before sending it with POST.
This is what my new Angular Post request code looked like:
sendEmail: function(email) {
var config = {
headers: {
'Content-Type': 'text/plain'
}
};
var POSTDATA= JSON.stringify(POSTDATAJSON);
return $http.post(POSTURL, POSTDATA, config)
}
And in Node.js this, I am using the cors Node.js module:
app.post('/mail', parse_post(function(req, res) {
var postReq = JSON.parse(Object.keys(req.body));
}));

Node JS: Where is my POST data?

I have no lack with sending POST request to node js server. I have a simple request and a simple server.
My server code is:
var http = require('http');
var bodyParser = require('body-parser');
http.createServer(function (req, res) {
console.log(req.body);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/')
my client request code is:
var val = JSON.stringify({ city:"SomeCity", name:"MyNameIsHere" });
alert(val);
$.ajax({
url: 'http://127.0.0.1:1337',
type: 'POST',
data: { value: val},
success: function(result) {
alert('the request was successfully sent to the server');}
});
So I suppose to get SomeCity and MyNameIsHere strings in the request body at the node js server, but the req.body field is undefined. Have to say that I open my test.html with request code locally with URL like this:
file:///D:/Projects/test.html
May be Im blind and overseen something trivial, but I have no idea what:)
Have to say that I open my test.html with request code locally with URL like this:
file:///D:/Projects/test.html
You're trying to post cross-domain, which you cannot do in this case. Serve your HTML over HTTP so that you can make a POST. If you use your browser's development tools, you will see that the request will never hit your Node.js server (except for a possible pre-flight request for CORS).
Another problem is that you're not actually using body-parser. If you want the post data, you will have to read from req like a stream.
You are including "body-parser" in var bodyParser = require('body-parser');, but you never actually use it. It won't magically parse the request for you. The default request object does not have a body property... see the documentation.
If you want to use the body-parser module, you should probably use express.js and read the documentation on how to connect it as middleware.
If you want to get the body using the built-in http server, you need to consume the request object first using something like this:
if (req.method == 'POST') {
var body = '';
req.on('data', function(data) {
body += data;
if (body.length > 1000000) {
req.connection.destroy();
}
});
req.on('end', function () {
console.log(req.body);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
});
}
Adding express library and bodyparser as middleware did the trick. However I could use the code from neelsg answer but working with built-in http server and handling Post data by my own is too burdensome.
So piece of my working code is here:
var express = require('express');
var http = require('http');
var url = require('url');
var bodyParser = require('body-parser');
var app = express();
app.use(express.bodyParser(
{
keepExtensions: true,
limit: 30*1024*1024 // lets handle big data
}
));
app.use(bodyParser.urlencoded());
Bodyparser by default can handle only 100Kb data in the post request, so I had to increase limit using its config options.

Resources