Browser URLs and HTTP requests - node.js

I'm currently building a web portfolio that combines many smaller web apps that I've made in the past. At the route (/) you find a page with links to these other smaller web apps. For instance, there's a link to route (/board-game) which takes you to the small board-game web app I made in the past.
What I'm struggling with is this. The smaller web app board-game serves it's html, css, and javascript to routes that don't include the prefix route (/board-game). So when a board-game page makes a request for (/css/style.css) nothing is loaded because the content is actually at (/board-game/css/style.css).
My question is this. Is there a way to re-route these requests to the appropriate route? I would like to avoid rewriting any part of these smaller projects. Any suggestions? Thank you.
Also, this is my current nginx.conf file.
worker_processes 1;
events {
worker_connections 1024;
}
http {
upstream portfolio {
server portfolio-svc:8080;
}
upstream board-game {
server board-game-svc:8080;
}
server {
listen 80;
location / {
proxy_pass http://portfolio/;
}
location /board-game {
proxy_pass http://board-game/;
}
}
}

You need to rewrite the path as part of the location, for example:
worker_processes 1;
events {
worker_connections 1024;
}
http {
upstream portfolio {
server portfolio-svc:8080;
}
upstream board-game {
server board-game-svc:8080;
}
server {
listen 80;
location = / {
proxy_pass http://portfolio/;
}
location = /board-game {
proxy_pass http://board-game/;
rewrite ^(.*)board-game(.*)$ http://board-game/$2 permanent;
sub_filter /css/ /board-game/css/
}
}
}
You might have to play with the matching a bit, but that's the general idea.

Related

How to redirect all except main page with NGINX?

This is my NGINX conf file:
server {
listen 80;
listen [::]:80;
server_name other.com;
root /home/user/html;
location = / {
}
location / {
return 301 https://mydom.com$request_uri;
}
}
It suppose to redirect every request except main route ("/"). But now it redirect everything with main route too. Where is my mistake?
Your location = / block isolates a single URI - the original request.
By default, Nginx processes any request that ends with a /, by checking if it resolves to a directory, and checking the directory for any files matching those listed in the index directive (default: index.html).
The index directive causes an internal redirection which causes Nginx to repeat the search for a matching location.
You will also need to isolate the redirected request.
For example:
location = / { }
location = /index.html { }
location / { ... }
Alternatively, bypass the index directive and handle it a single location using a try_files statement.
For example:
location = / { try_files /index.html =404; }
location / { ... }
See this document for details.

How to rewrite /api/a/b/c to d.com/a/b/c in Caddy

In Caddy, I'd like to make all incoming /api/* to redirect to d.com/*.
For example /api/a/b/c to d.com/a/b/c
How to achieve this in caddy?
Use a reverse proxy. Let's assume that you are listening on port 80 for all hosts, your Caddyfile would end up like this.
:80 {
rewrite / {
if {path} has api
r /api/(.*)
to /{1}
}
proxy / https://d.com/ {
transparent
}
}
Another way would be:
:80 {
rewrite /api {
r (.*)
to /{1}
}
proxy / https://d.com/ {
transparent
}
}

Can we use NGINX as webapp for template engine

I have a requirement for basic html template webapp such as:
http://localhost:3000/myapp?param1=hello&param2=John is called it should return text/html response which looks like this:
<html>
<body>
<p>Nice to see you John. Platform greets you "hello".</p>
</body>
</html>
the name and greeting is templated from param. so template is something like this:
<html>
<body>
<p>Nice to see you {{param1}}. Platform greets you "{{param2}}".</p>
</body>
</html>
I have currently done this in node server using express.js and then the server is exposed publicly via nginx.conf:
server {
listen 80;
# server_name example.com;
location / {
proxy_pass http://private_ip_address:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
I was wondering if this could be possible with some plugins or other configuration with bare nginx without hosting the node server on 3000 port.
I was able to solve this using only Nginx to program it using OpenResty's lua module.
The https://github.com/openresty/lua-nginx-module gives ability to program in nginx.conf, where one could use the existing lua libraries such as https://github.com/bungle/lua-resty-template for templating!
myapp.lua:
local template = require("resty.template")
local template_string = ngx.location.capture("/templates/greet.html")
template.render(template_string.body, {
param1 = ngx.req.get_uri_args()["param1"],
param2 = ngx.req.get_uri_args()["param2"]
})
greet.html:
<html>
<body>
<p>Nice to see you {{param1}}. Platform greets you "{{param2}}".</p>
</body>
</html>
nginx.conf:
worker_processes 1;
error_log logs/error.log;
events {
worker_connections 1024;
}
http {
root ./;
server {
listen 8090;
location /myapp {
default_type text/html;
content_by_lua_file ./lua/myapp.lua;
}
}
content_by_lua_file is where the power of openresty comes.
I described the complete process here: https://yogin16.github.io/2018/03/04/nginx-template-engine/
Hopefully, someone would find this helpful.
You can't render file with nginx.
Just send the file with nginx and the rewrite directive then inside the file just include some javascript to replace text content with query parameters
Nginx conf :
location / {
rewrite ^ /static/index.html break;
}
index.html:
<div>My content <span id="name"></span></div>
<script>
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
document.getElementById("name").textContent = getParameterByName("foo"):
</script>

Magento2 not reading my requirejs-config.js

I'm new to Magento2 and trying to figure out how RequireJS works in Magento.
Here is my situation:
I have following module:
app/code/Mymodule/Test/view/frontend/requirejs-config.js
Here is the content of this file:
var config = {
map: {
'*': {
jQuery110: "Mymodule_Test/js/jquery-1.10.2",
jqueryNoConflict: 'Mymodule_Test/js/jquery.no-conflict',
flexslider: 'Mymodule_Test/js/jquery.flexslider-min',
header: 'Mymodule_Test/js/store/header'
}
}
};
My theme is at this location:
app/design/frontend/Mycompany/Basic
My Javascripts are at following location:
app/code/Mymodule/Test/view/frontend/web/js/jquery.no-conflict.js
app/code/Mymodule/Test/view/frontend/web/js/jquery.flexslider-min.js
app/code/Mymodule/Test/view/frontend/web/js/store/header.js
In the PHTML file:
app/code/Mymodule/Test/view/frontend/templates/home.phtml
I added the lines:
require(['jqueryNoConflict', 'flexslider'],function($, flexslider){
(function($) {
$(window).load(function () {
$('.flexslider').flexslider();
});
})(jQuery);
});
When I check my page in browser, I get 404 error with paths:
http://mag2.com.local/pub/static/frontend/Mycompany/Basic/en_US/flexslider.js
But if I change the require[] line to this:
require(['Mymodule_Test/js/jquery.no-conflict', 'Mymodule_Test/js/jquery.flexslider-min'],function($, flexslider){
(function() {
$(window).load(function () {
$('.flexslider').flexslider();
});
})(jQuery);
});
the files are loading.
I also cleared the cache, my theme is correct, I executed the command:
php bin/magento setup:static-content:deploy
So, I am not able to figure out why my requirejs-config.js is not loading. I followed the documentation as well.
I found the problem.
Under pub/static/_requirejs/frontend/Namespace/Theme/en_US, delete the file requirejs-config.js.
Refresh your page and it will be generated again with new content.
This may help someone else with a very similar issue on local with nginx. The /static block was not rewriting correctly and this needed to be added per this comment https://github.com/magento/magento2/issues/7869#issuecomment-268585438
location /static/ {
if ($MAGE_MODE = "production") {
expires max;
}
# Remove signature of the static files that is used to overcome the browser cache
location ~ ^/static/version {
rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last;
}
location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ {
add_header Cache-Control "public";
add_header X-Frame-Options "SAMEORIGIN";
expires +1y;
if (!-f $request_filename) {
rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
}
}
location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
add_header Cache-Control "no-store";
add_header X-Frame-Options "SAMEORIGIN";
expires off;
if (!-f $request_filename) {
rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
}
}
if (!-f $request_filename) {
rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
}
add_header X-Frame-Options "SAMEORIGIN";
}
The detailed explanation is here
As requested by other members, adding the important bits:
Check if you can find the file it's trying to load on the filesystem. If it's there, it would point to a web server configuration problem instead. If it's not check file permission and then do static content deploy.

nodejs serve pre-compressed gz file

I have a .gz file located at /public/files/update.tar.gz. I would like to serve it for downloading using the route /ud/files/update.tar.gz. I would like to do it as static content and also with route (as some files will have a dynamic generated route).
I've tried the following for static (Actually achieved with nginx wich maybe is even better):
main.use('/ud/files', express.static(path.join(__dirname, 'public/files')));
Here I get the error:
Error: No default engine was specified and no extension was provided. at new View (bla bla)
And for dynamic url at /ud/files/tX2r8z/update.tar.gz:
router.get('/ud/files/:s/:file', function(req, res) {
checkSg(req.params.s, function(err) {
if(!err) {
res.download("/public/files/" + req.params.file, req.params.file); 'also tried sendFile()
} else {
res.send(404);
}
});
});
Here I get two errors toghether:
Error: Forbidden at SendStream.error (bla bla)
Error: No default engine was specified and no extension was provided. at new View (bla bla)
Any ideas?
Ok, found the solution: the first one it was a configuration problem as nginx was rewriting the path in order to serve the file itself (Right now I'm wondering why it wasn't served by nginx and the request was sent to node...):
location ~ ^/(ud\/files)/ {
rewrite ^/ud\/files(/.*)$ $1 last;
root /mnt/data/public/files;
gzip_static on;
add_header Cache-Control public;
}
location / {
proxy_pass http://127.0.0.1:3000;
}
So node was seeing a GET /updates.tar.gz
The second one has been solved as stated in this thread:
res.download(path.resolve("public/files/" + req.params.file));

Resources