jQuery callback function not working for cross domain - javascript

I'm using
nodejs in backend at localhost:3000
and
http Apache server at localhost:8080
$.post("http://localhost:3000", {data:"data"}, function(){alert("hurrah");});
// that one not working
$.get("http://localhost:3000", {data:"data"}, function(){alert("hurrah");});
// is working, but callback function not working

Have you checked out Cors for NodeJS?
Cross Domain requests may be blocked to your web server and if you're running NodeJS, you can add Cors(), configure the content you wish to accept (or accept all for the sake of debugging / time at the moment).
Depending on your NodeJS configuration you can set this up by including it at the top of your main class.
A default configuration, using Express might look something like this... (note this accepts all content!)
var express = require('express');
var app = express();
var cors = require('cors');
app.use(cors());
app.listen(8080, () => {
console.log('Listening on 8080');
});

Related

Why can i not connect to NodeJS express server from any network?

Lets say that i have a web server running on port 3001 and my ip is 23.512.531.56 (not an actual ip address btw) and i go onto another network, like my neighbours or something, if i type in chrome 23.512.531.56:3001why can i not get a response from the server? here is my nodeJS code.
//"Imports" libraries reqired.
const express = require("express");
const fs = require("fs");
//Starts express
const svr = express();
//Main
svr.get("/", (req, res)=>{
fs.createReadStream("./html/index.html").pipe(res);
});
svr.get("/image0.png", (req, res) => {
fs.createReadStream("./html/image0.png").pipe(res);
});
//Sets port to host on
svr.listen(3001);
You need to be in the same network. For example, if you are using different wifi (from your neighbors) you can't access your local NodeJs server. You can get to your server if your devices are under the same default gateway.
If you want to access it from any network, you might want to deploy it to a global network.
One thing to add, even for illustration don't use an IP address that is not right
You must open port 3001 to the outside and bind to your local machine (Port forwarding). Have a look into your router! And if it is not a fixed IP use a DynDNS service.

Node.js client can't see data from Express server

I am setting up a Client/Server communication between my tablet and my PC. My Client cant get any data from the server, what am I doing wrong.
My PC is running a Node.js server (using Express) and my tablet runs a client written in Node.js (using Express). I can access the server via the browser and get the data, but not through the javascript code.
My SERVER code is:
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('App requested a connection');
});
app.listen(3000, () => console.log('Listening on port 3000!'));
app.get("/boxes", function (req, res)
{
//res.send(req.params[0]);
res.send("All boxes are in the basement");
});
My CLIENT code is:
const express = require('express');
const app = express();
console.log("Client working ...");
app.get("http://127.0.0.1:3000/boxes", function (req, res)
{
console.log("inside...");
console.log(res);
});
The CLIENT should return "All boxes are in the basement" and I get this when I use a browser but it doesn't work if I run the client code. The only message I get from client is "Client working ...".
Does anybody know what I am doing wrong?
Cheers
Express is a library for setting up and configuring an http server for incoming requests. It does not make outgoing requests to other servers. So, your client code is not a client at all.
Several problems here:
127.0.0.1 refers to your local device so your client is referring to itself when it uses 127.0.0.1.
In your client app.get("http://127.0.0.1:3000/boxes") is not a request for data. That attempts to set up an Express route for incoming requests as if you were declaring a second server. But, it's not even done correctly because you would only use the path there.
For a client to make a request of some other server, you would need to use a library call that actually does http requests. For example, you could do something like this:
Code:
const rp = require('request-promise');
rp.get("http://ipaddressOfServer:3000/boxes").then(data => {
// have response here
}).catch(err => {
// error here
});
I chose to use the request-promise library, but there are multiple different ways to make an http request. You can also use http.get() (lower level), request() (from the request library) or axios() from the axios library, etc...
Note, the computer your server is on (assuming it's running a desktop OS) will also have to probably turn of it's local firewall (e.g. windows firewall) or set up a specific rule to allow incoming connections on port 3000. Without that, the incoming connection will be blocked (for security reasons).

Socket.io with two node.js servers?

I am a confused how to use socket.io so that two node servers can emit events between each other.
Server.js localhost:9200
io.sockets.on('connection', function(socket) {
socket.on('messageFromClient', function(data) {
socket.broadcast.to(data.chatRoom).emit('messageFromServer', data);
});
});
This socket connection listens to the server like so
var appPort = 9200;
var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io').listen(server);
// Launch server
server.listen(appPort);
I have a website being served by node.js... Server.js localhost:3000: I need this to be able to receive and emit events from localhost:9200
How do I setup server.js for localhost:3000?
I figured this out, it's really quite simple. There can be two node servers, but only one server needs to use socket.io and handle the events. All you need to do to connect is share the client side script via CORS, I wanted to avoid CORS, but you only need to share the socket.io script over CORS and nothing else, so it's not so bad.
First thing needed is to allow your other domain to access the script via CORS.
// requires cors module I think (var cors = require('cors');)
var corsOptions = {
origin: 'http://localhost:3100',
credentials: true
};
Then secondly, it's important client side to use io.connect I am not sure if that was depreciated or something but none of the modern docs mention this.
// What worked for me
var socket = io.connect('http://localhost:3100');
// Docs say
var socket = io('http://localhost:3100'); // ?? I am not sure why but io.connect worked for me.

How Can I Use Node.js With Cappuccino?

I'd like to have a client application implemented in Cappuccino that uses Node.js as the server.
I have currently got Node running with Express:
var express = require( 'express' );
var app = express();
app.get( '/an_endpoint', function(req, res){
res.send('Hello From Node Express!\n');
});
app.listen(1337);
Which is verifiable with:
$ node hello_echo.js
$ curl http://127.0.0.1:1337/an_endpoint
> Hello From Node Express!
As far as the client code, it's a simple little app, with a button that does this when clicked:
// in did finish launching
[button setTitle:"Ping Node"];
[button setTarget:self];
[button setAction:#selector(doPing:)];
- (void)doPing:(id)sender
{
var connection = [CPURLConnection connectionWithRequest:[CPURLRequest requestWithURL:'http://127.0.0.1:1337/an_endpoint/'] delegate:self];
}
- (void)connection:(CPURLConnection) connection didReceiveData:(CPString)data
{
alert('Node Says: ' + data);
}
- (void)connection:(CPURLConnection)connection didFailWithError:(CPString)error
{
alert('Error: ' + error);
}
When I load the app ( from http://127.0.0.1:8080/NewApplication/index.html ) and click the button, in Google Chrome, on OS X, I get the following errors in the console, the first due to the latter:
OPTIONS http://127.0.0.1:1337/an_endpoint/ 404 (Not Found) Objective-J.js:716
XMLHttpRequest cannot load http://127.0.0.1:1337/an_endpoint/.
Origin http://127.0.0.1:8080 is not allowed by Access-Control-Allow-Origin.
Which, is obviously due to the fact that my node server is at :1337, and my Cappuccino app is at :8080, which are technically different domains, due to the port part.
A bit of research led me to this post, which recommends considering the use of JSONP to inject remote scripts into the app. It sounds very messy, so I'd like to not go that route if not necessary.
So, my question is, how can I allow Cappuccino and Node.js to work together in harmony? It seems that if I can tell the Cappuccino app to use this ( header("Access-Control-Allow-Origin", "*"); ) header, all should be well, but I'm not sure how to do that. I tried having Node send that header, and it didn't seem to do anything.
You should use node to serve up the Cappuccino application so it's all on the same port.
The problem here is lack of configuration for CORS protection (Cross Origin Resource Sharing).
Somewhat simplified: The backend checks to see if the frontend is allowed to connect to the resource by checking to see if the request comes from the same server (protocol, domain, host, and port). in your case, the port is different and therefor the backend says NO and the frontend doesn't even actually perform the request. (This all happens in a preflight check).
In order to really solve this issue, you should learn about CORS but you really only need to do that if you plan to deploy something out of development. until then, you can just 'enable CORS' on your backend so it'll allow the frontend access:
var express = require( 'express' );
var cors = require( 'cors' );
var app = express();
app.use(cors);
app.get( '/an_endpoint', function(req, res){
res.send('Hello From Node Express!\n');
});
app.listen(1337);
This will allow all referers through to your code. Here are some more granular examples

Can I configure expressjs to serve some pages over http and others over https?

Based on the response to this question:
How do I configure nodejs/expressjs to serve pages over https?
I've been trying to set up the equivalent of:
var express = require('express');
var fs = require("fs");
var crypto = require('crypto');
var app = express.createServer();
var appSecure = express.createServer();
var privateKey = fs.readFileSync('privatekey.pem').toString();
var certificate = fs.readFileSync('certificate.pem').toString();
var credentials = crypto.createCredentials({key: privateKey, cert: certificate});
appSecure.setSecure(credentials);
app.get('/secretStuff', function(req,res) {
//redirect to https
}
appSecure.get('/secretStuff', function(req, res) {
//show you the secret stuff
}
Is this something that's doable with the current release of expressjs and node 2.4?
Yes, this can be done and it looks like you already have most of what you need. Just send the redirect in your app.get handler
app.get('/secretStuff', function(req,res) {
res.redirect('https://' + req.header('Host') + req.url);
}
Also make sure you do something like app.listen(80) and appSecure.listen(443) to actually start the servers on the appropriate port. Otherwise be sure to construct the HTTPS URL with the correct port. For production, this thing is typically handled outside of your app server (node.js) with a reverse proxy like nginx. It is trivial to do this in nginx which will let your node.js process run as non-root and remove the need to have clients directly connecting to node.js, which is not as battle-hardened as nginx for serving live internect TCP connections (I'm paraphrasing Ryan Dahl himself here).
You can only serve a web page over the connection that the request came in. If the request did not come in over https, you can't send the response that way.
So, first you have to be listening for both http and https requests. If a request comes in over http that you want to answer over a secure connection, do not do any processing but immediately redirect it to an https url. Then when the client reissues the request, process as normally.
If the framework uses JSGI then you can probably use the redirect module from Jack otherwise you will have to do it yourself. The details are at the link, i.e. response code 301 and Location: header with the https URL.

Categories