How can I get the current URL from app request in Node JS/ Express? - node.js

I don't know if it is possible but im trying to save the URL that came from app.use in a global variable and trying to access it in the next line. It turns that in the second line the variable is undefined.
Here is my code in my Node JS file:
app.use(function(req, res, next) {
global.CurrentURL = req.protocol + "://" + req.get('host') + req.originalUrl;
});
console.log(global.CurrentURL);
enter image description here
I need to save the current URL in the page so I can make validations with it. I think that the program doesn't go through that piece of code (app.use) is there any way I can force it to go through?

Related

serve same response just change url

I am using React with webpack and Nodejs. Now when this is hit on network tab http://localhost:8080/abc.js after clicking a button then the abc.js file gets downloaded.
Now I want to change the url still server the abc.js file.
Example after clicking the same button abc.js file will get downloaded but now the url would be like http://localhost:8080/abc.js/checking
I tried this:
app.use(function(req, res, next) {
if(req.path = '/abc.js')
req.path = req.url = '/checking';
return next();
});
But its not working. What would be the correct aproach.

Google cloud functions replaces double slash in url

Im trying to deploy cors-anywhere on Google Cloud Functions. Im supposed to provide the url after gcp's link.
It looks like this :
https://us-central1-my-project.cloudfunctions.net/my-function/http://dummy.restapiexample.com/api/v1/employees
but it's transformed to :
https://us-central1-my-project.cloudfunctions.net/my-function/http:/dummy.restapiexample.com/api/v1/employees
All the double slashes after the host are transformed to simple ones.
I tried replacing req.url to transform http:/ to http:// but still wont work. Maybe this needs to be fixed in the webserver level.
Here's my function in GCP
var cors_proxy = require('cors-anywhere').createServer({
requireHeader: ['origin', 'x-requested-with'],
removeHeaders: [
'cookie',
'cookie2',
],
// See README.md for other options
});
exports.myFunction = (req, res) => {
req.url = req.url.replace('/my-function/', '/'); // Strip '/my-function' from the front of the URL, else the proxy won't work.
return cors_proxy.emit('request', req, res);
};
Anyone tried to deploy this in a serverless function?
You're using req.url which contains a normalized version of the request URL. You'll want to use req.originalUrl which, as the name suggests, retains the original requested URL. See Express docs for more info.

Nodejs dynamic OG tags

Using Express. Here's the route. It basically just passes the url params into a template that renders the OG tags.
router.get('/share/:redirectURL/:title/:description/:img', function (req, res) {
var url = req.protocol + '://' + req.get('host') + req.originalUrl; // points to this endpoint
res.render('share', {
url: url,
title: decodeURIComponent(req.params.title),
img: decodeURIComponent(req.params.img),
description: decodeURIComponent(req.params.description),
redirectURL: decodeURIComponent(req.params.redirectURL)
});
});
module.exports = router;
And here's the share template that it renders to.
doctype html
html
head
meta(property="og:url", content="#{url}")
meta(property="og:image", content="#{img}")
meta(property="og:title", content="#{title}")
meta(property="og:description", content="#{description}")
meta(property="og:type", content="article")
body
script.
location.replace("#{redirectURL}");
...and it works! But it only works LOCALLY. As soon as I upload to the server, things go awry.
works: http://localhost/share/http%3A%2F%2Fgoogle.com/Hear%20some%20music./http%3A%2F%2F201.23.456.789%2F%2Fassets%2Fimgs%2Ffavicons%2Ficon1024.png
doesn't work: http://123.45.678.910/share/http%3A%2F%2Fgoogle.com/Hear%20some%20music./http%3A%2F%2F201.23.456.789%2F%2Fassets%2Fimgs%2Ffavicons%2Ficon1024.png
Something upstream is partially decoding the url BEFORE it gets to the Express router. The result is this confused, useless thing.
http://123.45.678.910/share/http:/google.com/Hear%20some%20music./http%3A%2F%2F201.23.456.789%2F%2Fassets%2Fimgs%2Ffavicons%2Ficon1024.png
Switched to query parameters and it works!

How to Redirect to Single Page Web App in Express for Node

I am writing a website with a single page web app (the rest of the website is just static files which are served). I am trying to write a piece of middleware for express to redirect all requests that follow the pattern 'example.com/app' to 'example.com/app' so that requests such as 'example.com/app/my/specific/page/' will all result in the same page being sent. The key issue with this is that the url in the address bar of the browser must not change so that the javascript app itself can interpret it and display the correct thing.
I could have done something like this:
app.use( '/app', function ( req, res ) {
res.redirect('/app');
});
However, this causes the url of the page to change and a separate HTTP request is assumedly made.
The most obvious alternative solution is to do something like this:
app.use( '/app', function ( req, res ) {
res.sendfile(__dirname + '/public/app/index.html');
});
The issue here is that resources from the page after requests like 'example.com/app/my/specific/page/' will look in the wrong location. For example, if I have an image on the page such as then it will look for example.com/app/my/specific/page/image.jpg. Since no image is returned, it will not display on the page. This happens for all external scripts or stylesheets.
I also tried something like this:
app.use( '/app', function ( req, res ) {
res.sendfile(__dirname + '/public/beta' + url.parse(req.url).pathname);
});
but that was very stupid of me for obvious reasons.
In the end I used this middleware to serve the app's page when appropriate
// all unmatched requests to this path, with no file extension, redirect to the dash page
app.use('/dash', function ( req, res, next ) {
// uri has a forward slash followed any number of any characters except full stops (up until the end of the string)
if (/\/[^.]*$/.test(req.url)) {
res.sendfile(__dirname + '/public/dash/index.html');
} else {
next();
}
});
I then set used a base HTML element with the href attribute pointed to the root.
If you're still trying to accomplish this I may have found a starting point. Alexander Beletsky has a Backbone.js + Express SPA boilerplate repo Located Here.
For a brief article on how it came about you can read his article on Dzone.

Cascade-like rendering with Express JS

With an express app running on a node server, how would I go about recursively searching for a render file from the full path right back to the beginning of the supplied URL.
For example, if someone was to hit my server with www.somewebsite.com/shop/products/product, the render engine would first check that there is an index.jade file in shop/products/product/. If none is found it would then check shop/products/, and subsequently shop/.
var express = require('express');
var app = express();
app.get('/*', function(req, res){
res.render(req.path + '/index.jade', function(err, html){
// some loopback code which alters the path and recalls the render method
})
});
The problem is that the response object is not passed to the render callback, so I'm unable to recall render on the response. I'm looking to create a loop because the URL paths may be any number of directories deep, so I can't just assume I only need to cascade for a definitive number of times.
Anyone see a way round this?
You should be able to use the response object from the closure. I think (assuming express allows you to call res.render a second time) you could use code like this answer to achieve what you want:
var express = require('express');
var app = express();
app.get('/*', tryRender);
function tryRender(req, res){
res.render(req.path + '/index.jade', function(err, html){
if (err) {
req.path = 'mynewpath';
tryRender(req, res);
}
})
}
Note: You will need to add a base case or this function will recurse infinitely if it doesn't find a view that works :D
In the event that express doesn't allow a subsequent call to res.render, you'll probably need to find out if the file exists on the file system yourself.

Resources