Using Nodejs and Express 4, I am trying to do a post on
my express server which in turn will take inputs from browser
and do a post on external server as a CORS workaround.
This the route to my server:
app.post('/api', api.postme);
This is my api.js file.
exports.postme = function (req, res, next) {
res.send("hello Apis");
};
For Example an external server:
https://website/NoJSONPHere/
params: page=1, query="frogs"
Is it possible to do this??
Use a second node server, host it somewhere in the cloud.
Then have mobile (blocked) app make calls against your server.
So,
your app> your server > their server.
Avoids,
your app > their server.
The reason this works is server to server connections or not blocked.
Browser to server is sometimes blocked.
Related
I have a node express server responding to http traffic:
const http = require("http");
const express = require("express");
const app = express();
const server = http.createServer(app);
app.use(function(req,res,next){
console.log(`logging: req: ${util.inspect(req)}`);
next();
});
and all that works fine. I'd like to have a program on my node server inject emulated http traffic into the express stack, without a network connection. I can't just magic up a (req,res) pair and call a middleware function like the one in app.use above, because I don't have a next to give it, and my req and res will not be the ones next passes on to the next middleware in the stack.
Edit: What I actually have is a websocket connection sending data packets of a different format, different data contents from http traffic that can also carry the same information. I can take those websocket packets and build from those a request that is in the same format that the http traffic uses. I would like to pass that transformed request through the express http middleware stack and have it processed in the same way. Going all the way back to create an http request having just dealt with a ws request seems a bit far.
What's the simplest way to emulate some traffic, please? Can I call a function on app? Call some express middleware, or write a middleware of my own to inject traffic? Call a function on server?
Thanks!
Emulation traffic by calling some Express.js internal functions isn't the right way. Much easier is to trigger the server by HTTP request from the same process
const http = require('http');
const util = require('util');
const express = require('express');
const app = express();
const server = http.createServer(app);
app.use(function(req, res, next) {
console.log(`logging: req: ${util.inspect(req)}`);
next();
});
const port = 8081;
server.listen(port);
http.request({ port }).end();
From your question
I'd like to have a program on my node server inject emulated http traffic into the express stack, without a network connection
Can you clarify, why without a network connection?
A few things:
You need to make an endpoint
You need to host your server somewhere
You need something to send requests to your server
Express provides you a way to receive requests (req, res) (might be from a browser, might not be), perform some operations, and return responses (req, res) to the requester.
The expression
app.use(function(req,res,next){
console.log(`logging: req: ${util.inspect(req)}`);
next();
});
is actually a middleware function. This will take every request to your server and change the request object created by express into a string, and print it in your server log.
If you want a testable endpoint, you would add this to the bottom of the snippet you posted
app.get('/test', function (req, res) {
res.json({success:true})
})
This tells your app to allow GET requests at the endpoint /test
Next you're going to need to host your express server somewhere you can send requests to it. Your local machine (localhost) is a good place to do that. That way, you don't need an internet connection.
Pick a port you want to host the server on, and then it will be reachable at http://localhost:<Your Port>.
Something like this will host a server on http://localhost:3000. Add this below the route we declared above:
server.listen(3000, function() {
console.log('Server running on port 3000');
});
Finally, you'll need a way to send requests to the server on localhost. Postman is a great tool for testing express routes.
I would suggest installing Postman and using that to emulate http traffic.
Once your server is running, open postman and send a GET request to your server by entering the server address and port, and hitting the blue send button (You'll be sending the request to http://localhost:3000/test).
Here's an image of what postman should look like if all goes well
You should also see your middleware fire and print out the request object in your terminal.
Good Luck!
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").
The Problem
I have a server (node.js) on localhost port 8080, with the client running on 3000. In order to run my web app, I run both concurrently, but only use the server as a proxy for the client to bypass CORS requests - it does not serve any static pages. I have found that although making API calls from client code to the server works perfectly fine (or a script that makes unirest requests), I cannot test simple routes on the browser on localhost:8080/[route], such as this one:
app.get('/login', (req, res) => {
console.log('serving login');
res.send('login');
})
//on the Google Chrome browser: localhost:8080/login
The Question
The /login route never gets triggered. Is my URL incorrect on the browser? If so, how can I correct it?
Side Note
This may/may not change anything, but I am using React Router HashHistory for my client side. Interestingly when I type in localhost:8080/login into the browser, it automatically converts to localhost:8080/login#/.
I need to query a database and I'm using create-react-app. The library to connect to the DB (pg-promise) does not work with Webpack and needs to be running on a Node server.
So I installed Express and have this:
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, '..', 'build', 'index.html'));
})
How can I load data from the database from the React pages? I though of using request but how can I make a request to my own server? And what should I add to the lines of code above? I think it would be something like:
app.get('/query/:querybody', (req, res) => {
// process and return query
})
Is this right? How can I make it work with a SPA?
Probably the most friction-free method would be to have a separate app.js or server.js along side your CRA application. You can use a tool like concurrently to run both your React app and the express app.
The trick is to serve your express app on a different port than the default :8080 that CRA serves on. Usually 8081 is a good choice, as it's a common convention to use port numbers that are close together when developing.
In your React app, you will need to make sure you use the full URL for the express endpoint: http://localhost:8081/query/...
On the server side you are going in the correct direction: you need to setup endpoint which will respond with data based on request. In you example you setup an endpoint for a GET HTTP request. If you will need to pass a complex request (for example add new record to database), consider using POST HTTP requests.
On the client side (in the browser) you will need a library that will assist you in sending requests to your server. I can recommend to try Axios (https://github.com/mzabriskie/axios). Usually if you omit protocol, server name and port, request will be sent to the server from which the page was loaded:
http:127.0.0.1:8001/api/endpoint => /api/endpoint
I wrote an express app as an HTTP proxy, to intercept and analyse some of the network traffic. The parts of traffic my app is interested in are all HTTP, however I still want my app to proxy HTTPS so users can use it without extra setting.
My express app is created with a HTTP server. When testing, I changed the proxy setting in Chrome with SwitchyOmega, to proxy HTTPS connections with HTTP. HTTP works well, But my express app couldn't get these proxy requests for HTTPS.
So I wrote a simple TCP proxy to check on them, and find that they're like this:
CONNECT HOSTNAME:443 HTTP/1.1
Host: HOSTNAME
Proxy-Connection: keep-alive
User-Agent: MY_AGENT
ENCRYPTED HTTPS
I believe these requests are HTTP, but why express isn't receiving them?
For sure if I change the browser proxy setting to ignore HTTPS, the app works well. But I do want to know if there is any workaround that I can use to proxy all protocols with HTTP and only one port.
THX.
UPDATE- code from my express app
app.use('*', function (req, res, next) {
// print all the request the app receive
console.log('received:', req.url)
})
app.use(bodyParser.text({type: '*/*'}))
app.use(cookieParser())
app.use(logger('dev'))
app.use(express.static(path.join(__dirname, 'public')))
// serve web pages for my app, only the request targeting my server
// is handled here(right IP and port), proxy request gets handled after this.
app.use('/', internalRoute)
// analyse the part I want
app.use('/END_POINT_I_WANT', myRoute)
// handle proxy requests
app.use('*', function (req, res, next) {
// proxy the request here
})
The problem is, my first middleware, which is used to display all the requests the app receive, can't catch the HTTPS proxy requests wrapped in HTTP described above. And of course the middleware I used as proxy can't catch them either.
UPDATE-tried node-http-prxoy, no luck
var httpProxy = require('http-proxy')
, http = require('http')
, fs = require('fs')
var options = {target: 'http://127.0.0.1:8099'}
, proxy = httpProxy.createServer(options)
http.createServer(function (req, res) {
console.log(req.url)
proxy.web(req, res)
}).listen(5050)
With the above code, and browser setting to proxy all protocols with HTTP, it works the same as my express app. HTTPS proxy requests gets ERR_EMPTY_RESPONSE, and nothing on the console.
With the below options, it seems that I have to change the proxy protocol to HTTPS, which I'd rather not use, at least for now. And I get ERR_PROXY_CERTIFICATE_INVALID for my self-signed certs...
var options = { secure: true
, target: 'http://127.0.0.1:8099'
, ssl: { key: fs.readFileSync('cert/key.pem', 'utf8')
, cert: fs.readFileSync('cert/server.crt', 'utf8')
}
}
UPDATE- pin point the problem to the 'connect' event listener
Through some searching, I found this post helpful.
It pointed out that the http server doesn't have a listener for the connect event. I tried the code in the post, works. But as the last comment of that post mentioned, my app serves as a proxy in order to get the data, it then proxy the request to another proxy in order to go over the GreatFireWall.
The process is like : BROWSER -> MY_APP -> ANOTHER_PROXY -> TARGET.
Without the ANOTHER_PROXY, which is an HTTP proxy, it works well for both HTTP and HTTPS. However I failed to chain them all up. The ANOTHER_PROXY I use supports HTTPS over HTTP.
It's hard to see what might be wrong, since you haven't posted any code.
However, if you just want to create a simple proxy that supports HTTP and HTTPS, i think that you should consider using a module like node-http-proxy.
Their readme has example code for the most common scenarios, and it sounds like it will support your needs fine.