I'm implementing angular static application with ui-routes and nginx as a web server. My Angular routes code:
$urlRouterProvider.otherwise('/home');
$locationProvider.html5Mode({
enabled: false,
requireBase: false
});
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/views/homePage.html'
});
And nginx.conf
location / {
root html/MySite;
index index.html index.htm;
}
When i type localhost in the browser address bar it is redirecting to my site home page and url will changing to http://locahost/home after this when refresh page page it will redirecting to nginx 404 page, and when i type http://locahost/home in address bar then also it is redirecting nginx 404 page.
Nginx location should be like:
server {
server_name localhost;
root html/MySite;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
Then it will redirect to you index.html
Related
We encountered a very weird behavior when using Nginx as a reverse proxy.
We have REST services that need to be used with the browser, We configured these HTTP Golang services to handle CORS using cors package.
We noticed that when the browser triggers a preflight request the request doesn't go to the backend service and instead Nginx responds with the status 405 Method Not Allowed and the request is never forwarded or proxied to the backend service at all.
To fix this issue we had to handle OPTIONS requests manually from the location directive, This is very limited as we need the liberty to update for example the allowed headers using Access-Control-Allow-Headers based on the requested route.
How can we forward any Preflight or OPTIONS request to the backend to handle?
NOTE: We are using default Nginx configurations according to the official Nginx docker image.
file: main.go
package main
import (
"net/http"
"github.com/rs/cors"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World"))
})
r := cors.AllowAll().Handler(mux)
http.ListenAndServe(":3000", r)
}
file: server.conf
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:3000;
# Handling OPTIONS for this location directive.
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "$http_origin";
add_header Access-Control-Allow-Credentials 'true';
add_header Access-Control-Allow-Headers 'Authorization, Content-Type, Origin, X-Requested-With, Accept';
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, PUT, DELETE';
add_header Content-Type 'text/plain; charset=utf-8';
return 204;
}
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Original-Remote-Addr $remote_addr;
proxy_set_header X-Original-Host $host;
}
}
Related:
Handling OPTIONS request in nginx
Cross Origin preflight request in Nginx Proxy
I am using Socket.IO in my application. The React client uses socket.io-client 4.1.3, and the Node.js server uses socket.io 4.1.3
In the development environment on my local machine, everything works fine.
The React app runs on http://localhost:3000, and connects to the server using:
import io from 'socket.io-client';
const socket = io('http://localhost:5000/');
The Node.js server is configured as below:
const express = require('express');
const app = express();
const server = require('http').createServer(app);
const cors = require('cors');
const io = require('socket.io')(server, {
cors: {
origin: 'http://localhost:3000'
},
maxHttpBufferSize: '1e6'
});
app.set('io', io);
app.use(express.static('public'));
app.use(express.json({ limit: '7mb' }));
app.use(cors({ origin: 'http://localhost:3000' }));
server.listen(5000, () => console.log('Server started'));
In production, I am using Firebase to host the React app, in a subdirectory (e.g. https://www.example.com/app/).
In production, http://localhost:5000/ and http://localhost:3000 in the code above have also been changed to https://app.example.com and https://www.example.com/app respectively.
My server uses Ubuntu 20.04, Nginx, and Let's Encrypt, with a server block set up as follows:
server {
server_name app.example.com;
location / {
proxy_pass http://localhost:5000/;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}server {
if ($host = app.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name app.example.com;
return 404; # managed by Certbot
}
In Google Chrome, I was getting No 'Access-Control-Allow-Origin' header is present on the requested resource as an error. Changing the origin from https://www.example.com/app to * in the Node.js code fixed this.
However, now I am getting the following error in my browser:
POST https://app.example.com/socket.io/?EIO=4&transport=polling&t=NirW_WK&sid=PmhwTyHRXOV4jWOdAAAF 400 (Bad Request)
Why would this be?
Thanks
A few small changes to both the Node.js and Nginx should resolve your problem:
Node.js
First off, I'd recommend that you change this:
cors: {
origin: 'http://localhost:3000'
},
to this (as specified here):
cors: {
origin: 'http://localhost:3000',
methods: ["GET", "POST"]
},
Nginx
Change this:
location / {
proxy_pass http://localhost:5000/;
}
to this:
location / {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
proxy_pass http://localhost:5000/;
}
This post here can help give more information on CORS headers needed in Nginx reverse proxies
Try adding a variable port to access an environment variable. PORT should be set to https://app.example.com/
const port = process.env.PORT || 3000
And use it everywhere that local host 3000 was used in your backend code.
This should also help
const io = require("socket.io")(server, {
cors: {
origin: port,
methods: ["GET", "POST"],
allowedHeaders: ['Access-Control-Allow-Origin'],
credentials: false
}
})
I was facing same issue and backend was on aws elasticbeanstalk, so we set Load Balancer, to handle multiple request calls and this error was fixed. So i think you need to check cloud base function for load balancing.
Scenario
I'm developing a web application using
Laravel 5.6.3
Vue 2.5.7
VueRouter 3.0.1
Setup
I'm using VueRouterlike
Vue.use(VueRouter);
import fooPage from './components/pages/fooPage.vue';
import barPage from './components/pages/barPage.vue';
const routes = [
{
path: '/foo',
component: fooPage
},
{
path: '/bar',
component: barPage,
}
]
const router = new VueRouter({
mode: 'history',
routes: routes
});
With
const app = new Vue({
el: '#app',
router,
})
And a:
<router-view></router-view>
In my markup.
Issue
When I perform a hard refresh on root (/), I can navigate between pages and the content loads fine. However, when I refresh on, say /foo - I can no longer navigate between the different pages properly.
You are probably looking towards this https://router.vuejs.org/en/essentials/history-mode.html.
Depending on your server's configuration, you should follow the steps in that web page.
I will copy apache and nginx ones since they are widely used.
Apache
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
Nginx
location / {
try_files $uri $uri/ /index.html;
}
I am on a Laravel project that works perfectly locally (GET, POST requests on forms as well as Ajax). The hard part is when I deploy it on nginx, everything works except Ajax calls. I simply don't have parameters passed to my controllers. I would have something like
$.ajax({
type: 'get',
url: '{{route('
test.route ') }}',
data: {
valuepassed: 5
},
success: function(data) {
alert(data);
}
})
with a controller returning the value passed like return Input::get('valuepassed') or return $request->valuepassed. I get the value when running it locally but when on nginx the param is empty.
Here is my config :
server {
listen 80;
listen [::]:80;
root /var/www/html/mydomain/public;
index index.php index.html index.htm index.nginx-debian.html;
server_name mydomain.com www.mydomain.com;
location / {
try_files $uri $uri/ /index.php?query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.1-fpm.sock;
}
PS: I'm kinda new to nginx
You seems to have a typo in your config. Below
try_files $uri $uri/ /index.php?query_string;
should be
try_files $uri $uri/ /index.php?$query_string;
You are passing a fixed param instead of one that you get from client. Changing query_string to $query_string should fix it
I need to disable the same origin policy on the server. Just as a background: I have verified that everything is working by starting chrome with the disable web security flag. Everything works as expected.
Here's what I have done on the nginx side:
upstream phpfcgi {
server unix:/var/run/php5-fpm.sock; #for PHP-FPM running on UNIX socket
}
server {
listen 80;
root /var/www/yammi2;
index index.html index.php index.htm;
server_name myserver.ch;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Credentials 'true';
add_header Access-Control-Allow-Headers 'Content-Type,accept,x-wsse,origin';
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, PUT, DELETE';
# strip app.php/ prefix if it is present
rewrite ^/app\.php/?(.*)$ /$1 permanent;
location / {
index app.php;
try_files $uri #rewriteapp;
}
location #rewriteapp {
rewrite ^(.*)$ /app.php/$1 last;
}
# pass the PHP scripts to FastCGI server from upstream phpfcgi
location ~ ^/(app|app_dev|config)\.php(/|$) {
fastcgi_pass phpfcgi;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
}
When I then do curl call: curl -I myserver.ch, I get the following result:
HTTP/1.1 302 Found
Server: nginx/1.1.19
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.3.10-1ubuntu3.9
Set-Cookie: PHPSESSID=gvcl3v533ib91l2c6v888gl9d3; path=/
cache-control: no-cache
date: Fri, 10 Jan 2014 07:01:18 GMT
location: http://myserver.ch/admin/restaurant
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type,accept,x-wsse,origin
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE
so at least it seems that the headers are set correctly, yet the result when I make the ajax call:
OPTIONS http://myserver.ch/api/v1/restaurant/closest?max=50&lat=47&lon=8 500 (Internal Server Error) jquery-2.0.3.js:7845
OPTIONS http://myserver.ch/api/v1/restaurant/closest?max=50&lat=47&lon=8 Origin http://localhost is not allowed by Access-Control-Allow-Origin. jquery-2.0.3.js:7845
XMLHttpRequest cannot load http://myserver.ch/api/v1/restaurant/closest?max=50&lat=47&lon=8. Origin http://localhost is not allowed by Access-Control-Allow-Origin. overview.html:1
I'm a bit confused by the "Internal Server Error", but I figured since it works with the flag, this has to be something to do with same origin.
The server application is a symphony app. I hope I haven't missed anything. Any idea how to fix this? Or even how to debug it?
Maybe one last snipped, here is how I make the call (again, shouldn't be the issue, because with the disable security flag it works as expected):
$.ajax({
url: url,
headers: {"x-wsse": getWsseHeader()},
beforeSend: function (request) {
request.setRequestHeader("x-wsse", getWsseHeader());
},
success: function() {
},
error: function(error) {
console.log(error.statusText);
}
});
Change this line
add_header Access-Control-Allow-Origin *;
as
add_header 'Access-Control-Allow-Origin' '';