Node.js Nginx POST request - node.js

I have a Node.js server with Express running on the same machine where Nginx is installed. This is my nginx code in sites-enabled:
upstream project {
server 192.168.0.102:3100;
}
server {
listen 80;
location / {
proxy_pass http://project;
}
}
With this config, when I type my domain on a public computer, the first page of my website shows up, so thats okay. But the webpage is a form where I should be able to upload data to my server, and when I press upload in my website, nothing happens. This is my sudo-code:
app.get("/", function(request,response){
//Code to send html page. This is the part where it runs fine.
});
app.post("/package/upload", function(request,response){
//Code to read from request.body and request.files and save uploaded file to my server.
//Nothing happens when I try to upload through a normal XMLHTTP object in my website.
});
I'm been working on servers for some time, but its my first time using nginx for server optimization and load-balancing. Can somebody help me what I'm missing?

(I can't comment, not enough rep)
It looks like you've setup the proxy_pass only on /. Have you tried defining your POST location /package/upload and the corresponding proxy_pass?
What do you see when you look at the Network panel in your browsers developer tools when you try to upload? HTTP Status codes help a ton when debugging.

Related

Https createServer, load cookie and load clients index.html

I am trying to setup a login system on a website.
In order to do that, I have to load http only cookies.
In order to load them, I have to send them back to the client via the response object in the createServer function when https starts up.
I have successfully done that via here:
setting up https cookie in nodejs
The problem is twofold.
The https server cookie only loads if I include the port number in the url.
How do I get it to load without including the port number?
When the server kicks in and loads the cookie, the static index.html that was always supposed to load on the client, doesn't load and instead all i get is what was written into the response object on the server. How do I get to load the cookie, and just load that static html file?
I have tried sending in the entire html file as a respnose from the server side. But I'm not sure about that, plus i get MIME type problems in the browser.
I am not sure for the first part but for 2nd one,
you have to properly mention about response data type in response header.
so your should be something like this one:
var app = express(); app.get('/test', function(req, res) { res.sendFile('views/test.html', {root:__dirname}) });
For your first part of the question "How do I get it to load without including the port number?" You can try creating virtual host e.g for localhost:3000 will be something.xyz.
And for your second part you need to serve index.html with render method as follow
server.get('/', function (req, res) {
res.render('index', { greeting: 'Welcome' });
});
Where index is you static file inside view directory.
I've created a small demo, that might get you on the right track:
https://github.com/bergur/simple-server-with-websocket
This example includes:
https web server
websocket server
logic to get the cookies
serving a temp.html file without express
example of javascript class
example of dependency injection in nodejs

Express routing hello world in the browser from their example docs does nothing

I want to serve html to the browser but for now just 'Hello World'
When I navigate to https://example.com/test
EDIT: my site is not example.com I just can't type the name
the console does not log a request
404 in the browser if I don't create the directory, 403 forbidden if I do create it.
node.js code:
var express=require(__dirname+'/../node_modules/express');
var app = express()
app.get('/test', function(req,res){
console.log(req);
res.send('Hello World')
})
app.listen(10001);
I get no node.js errors
the port 10001 is open!
I can't find any docs beyond http://expressjs.com/en/guide/routing.html which just assumes that what they tell you to do will just work so they go into ZERO detail!
I totally 100% do not understand this!
Where are you hosting? If local, are you including the port in your URL?
If you are using a local dev server, it should be something like
https://localhost:10001/test
You are trying to serve your app on a server at port 10001. If your domain is example.com, you have to go to http://example.com:10001/test. When you try to connect to the website using a browser, the browser will automatically assume the port is 80 and it will try to connect to that port.
Also you can use const express = require("express").

angular universal https problems

I have an angular universal app set up. I do POST requests on the server-side using localhost to pre-render my app and this works fine.
An example working url would be http://localhost:8000/api/get-info.
I've now put the app into production on an external url (apache server). I'm also using ssl.
Now when I try to do a POST request on the server-side to pre-render my app, I get back a response with status: 0, url: null (I'm assuming this means the connection was refused).
An example non-working url would be https://mywebsite.com/api/get-info.
What really stumps me is that when the app loads on the client, all HTTPS requests start working. So the problem is I cannot get the express server to send POST requests to my external url.
I've tested a post request on the server-side to a different website (twitter), and that seems to work fine as well. So i'm not entirely sure where I've gone wrong.
I already have CORS set to '*' as well.
Try using
http://localhost:8000/api/get-info
in production as well. Since your Angular app is rendered on the same server as your API is running, using localhost should just work fine. It doesn't matter if you are on an external URL.
I do something similar (its a GET but that shouldn't matter) with my translations:
if ( this.isServer ) {
translateLoader.setUrl( 'http://localhost:4000/assets/localization/' );
} else {
translateLoader.setUrl( 'assets/localization/' );
}
It works locally and in production (both server and client).
I just encountered this problem myself for two days. Please take a look at my comment on https://github.com/angular/universal/issues/856#issuecomment-426254727.
Basically what I did was I did a conditional check in Angular to see if the APP is running in browser or in server (rendered by Angular Universal), and change my API endpoint to actual IP in https or localhost in http accordingly. Also in my Nginx setting, I only redirect incoming request from browser to https by checking if the server_name is localhost.
Hope it helps!

Static sites with nginx and express.js - Authentification

My plan
In my app, I want to separate the backend from the frontend. I have multiple static sites with vue.js accessing an api provided by an express server. All static files should be served by nginx.
So for now my nginx config file looks like this:
http {
...
upstream backend {
server localhost:3000;
keepalive 64;
}
...
server {
...
location /api {
...
proxy_pass http://backend;
}
}
}
So all request to /api are handled by express running at port 3000. Users can login through the frontend that is accessing the backend api.
Now to the problem:
I have some sites (e.g. /dash) that are also static but should only be accessible for users that are authenticated (authentication is handled by express session) and with a specific user role (e.g. editor).
A user who is not an editor should get a error 403 when accessing /dash while for the others, /dash should be served by nginx.
I hope I was clear enough, it is not easy to express my problem properly. I appreciate any help and advice, maybe my approach is not a good idea or is a bad practice.
Edit
Solution can be found in comments of the right answer.
For starters, authorization to some static files should be handled in the backend-server and not in nginx. Nginx is just a proxy, and not a handler for authorization. Maybe check out passport if you're using express.
Secondly, I think you have the wrong idea about static files. A tip would be to compile them to make them smaller(check out http://nginx.org/en/docs/http/ngx_http_gzip_module.html). But that's how far nginx will handle your static files.

transmission rpc with expressjs

i currently have transmission-daemon web ui served by nginx
server {
listen 2324;
server_name torrent.example.com;
location /rpc {
proxy_pass http://127.0.0.1:9091/transmission/rpc;
}
location /transmission {
proxy_pass http://127.0.0.1:9091/transmission;
}
location / {
proxy_pass http://127.0.0.1:9091/transmission/web/;
}
}
i am trying to display this page via https://github.com/stormpath/stormpath-express-sample this dashboard/user interface
in routes/index.js i have
router.get('/torrent', function (req, res, next) {
if (!req.user || req.user.status !== 'ENABLED') {
return res.redirect('/login');
}
var newurl = 'http://127.0.0.1:2324'
request(newurl).pipe(res)
});
i see the html when i goto /torrent but no images/css/js i am thinking the request is not the right tool for this purpose could some one offer a better solution
many thanks
Your HTML probably refers to CSS/images/etc using URLs such as /index.css. The browser makes these into fully-qualified URLs that look like http://torrent.example.com/index.css, which is not proxied by ngnix the way you have it set up.
You probably want to either use URLs such as /transmission/index.css for your CSS (when specified in the HTML), or alternatively have a <base> tag in your HTML for that.
ok so i have made progress with html/css i moved the transmission interface into the express root and imported the html into jade but now i am having a new problem
when i load the /torrent page i can seen in the web console it makes a request to /rpc which i have made a route for
router.get('/rpc|/rpc/', function (req, res) {
var newurl = 'http://127.0.0.1:9091/torrent/rpc/'
request(newurl).pipe(res)
});
but this comes up with a 404 when i change router.get to router.post i get a 405 error
i have removed the 409 error from transmission so this should work
i have solved the issue
i imported the transmission index.html into a jade template
i routed /torrent to render that template
then i made a new route for /rpc|/rpc/ made that do a post request to the backend transmission-daemon
i also changed /js/remote.js to look for the RPC._Root at the atchual domain

Resources