There is vhost config, which should be reverse proxy to the flask application, and is not working. Below is the vhost config. Flask application is running on port 5000.
Added rewrite in both the context and outside, even then it's not working. Below config always gives the error 500.
vhDomain $VH_NAME
vhAliases www.$VH_NAME
enableGzip 1
enableIpGeo 1
index {
useServer 0
indexFiles index.php, index.html
}
errorlog $VH_ROOT/logs/$VH_NAME.error_log {
useServer 0
logLevel WARN
rollingSize 10M
}
accesslog $VH_ROOT/logs/$VH_NAME.access_log {
useServer 0
logFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i""
logHeaders 5
rollingSize 10M
keepDays 10
compressArchive 1
}
extprocessor pythonflask1709 {
type proxy
address 127.0.0.1:5000
maxConns 200
pcKeepAliveTimeout 60
initTimeout 20
retryTimeout 0
respBuffer 0
}
scripthandler {
add proxy:pythonflask1709 html
}
module cache {
storagePath /usr/local/lsws/cachedata/$VH_NAME
}
rewrite {
enable 1
autoLoadHtaccess 1
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
REWRITERULE ^(.*)$ HTTPS://127.0.0.1:5000/$1 [P]
}
context / {
type proxy
handler pythonflask1709
addDefaultCharset off
rewrite {
enable 1
autoLoadHtaccess 1
RewriteEngine On
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
REWRITERULE ^(.*)$ HTTP://127.0.0.1:5000/$1 [P]
}
}
For reverse proxy, you have created a Web Server External App named pythonflask1709 which is good. The next step is to set up a context, rewrite rules, or Script Handlers.
Context method
context / {
type proxy
handler demo
addDefaultCharset off
}
Rewrite method
REWRITERULE ^(.*)$ HTTP://pythonflask1709/$1 [P,L,E=PROXY-HOST:WWW.EXAMPLE.COM]
As you can see the above rule, use web server name pythonflask1709 in the rule instead of 127.0.0.1:5000, also please substitute WWW.EXAMPLE.COM with your real domain name.
Both should work, but please do not apply both methods at the same time.
Another solution is to run WSGI APP directly without proxy.
More, https://openlitespeed.org/kb/python-wsgi-applications/#Set_up_Flask_with_a_Virtual_Environment
The config you provided helped. I'm able to make it work with some tweaks. Here is config. i used.
extprocessor barwi5691 {
type proxy
address 127.0.0.1:5000
maxConns 200
pcKeepAliveTimeout 60
initTimeout 20
retryTimeout 0
}
scripthandler {
add proxy:barwi5691
}
context / {
type proxy
handler barwi5691
addDefaultCharset off
rewrite {
enable 1
autoLoadHtaccess 1
RewriteEngine On
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
REWRITERULE ^(.*)$ HTTP://127.0.0.1:5000/$1 [P]
}
}
rewrite {
enable 1
autoLoadHtaccess 1
}
Related
I'm running a Xampp Apache server on Windows and I'm trying to simply pass a value from a slider to my Node.js server. To do that I use the fetch method and post my values to /t/request.
If I replace "/t/request" with "http:localhost:3000/t/request" everything works fine locally, but not on any other machine, otherwise I get the "POST https://mywebsite.com/t/request 404 not found" error.
I am (to my knowledge) proxying Node.js in the Apache configs, so I can't see why I get this error whatever I do.
I have read that you need to set up SSL certificates for your Node.js server too, but I don't see why since Apache and Node.js communicate locally. Other people have said the same thing.
UPDATE: Changing http to https in the vhosts config file for proxying changes the error from a 404 to a 500.
My html js code that loads up on /t/imz7hyza
var sliderOutput = document.getElementById("rangeSlider");
sliderOutput.oninput = async function(){
try {
let obj = JSON.stringify({sliderVal: sliderOutput.value, buttonVal: buttonOutput.checked})
let obj2 = JSON.parse(obj)
const response = await fetch('/t/request', {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*' },
body: obj,
});
console.log(obj)
} catch(err) {
console.error(`Error: ${err}`);
}
}
My server.ts code
import express, { NextFunction, Request, Response } from "express";
import cors from "cors";
import bodyParser from "body-parser";
const app = express();
var jsonParser = bodyParser.json();
app.use(express.json());
app.use(cors({origin: '*'}));
app.use(express.static('public'));
interface IUpdateSlider{
sliderVal: number
buttonVal: boolean
}
app.post("/t/request", async (req: Request<{}, IUpdateSlider, IUpdateSlider>, res: Response) => {
try {
let number = req.body.sliderVal
if(req.body.buttonVal) console.log(number, "on")
else console.log(number, "off")
res.status(200).send({
msg: "Read!"
})
res.end();
} catch (error) {
console.error(error);
res.status(500).send({
msg: "Internal server error."
})
}
})
app.listen(3000, () => {
console.log("server listening to port 3000");
})
My Apache httpd.conf. I have proxy, proxy_http, proxy_ajp, rewrite, deflate, headers, proxy_balancer, proxy_connect and proxy_html enabled, along with the required ssl modules.
Define SRVROOT "C:/xampp/apache"
ServerRoot "C:/xampp/apache"
ProxyPass /t/imz7hyza http://localhost:3000/
Listen 80
--modules here
ServerName localhost
<Directory />
AllowOverride none
Require all denied
</Directory>
DocumentRoot "C:/xampp/htdocs"
...
<VirtualHost *:443>
ServerAdmin mymail#gmail.com
DocumentRoot "C:/xampp/htdocs"
ServerName www.mywebsite.com
ErrorLog "logs/error.log"
SSLEngine on
SSLCertificateFile "conf/ssl.crt/mywebsite_com.crt"
SSLCertificateKeyFile "C:/xampp/apache/bin/server.key"
SSLCertificateChainFile "conf/ssl.crt/mywebsite_com.ca-bundle"
</VirtualHost>
My .httaccess file
ErrorDocument 404 /404.html
DirectoryIndex /index.html
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
And finally my httpd-vhosts.conf file
<VirtualHost *:80>
ServerName www.mywebsite.com
Redirect permanent / https://mywebsite.com/
ProxyPass /t/request https://localhost:3000
ProxyPassReverse /t/request https://localhost:3000
</VirtualHost>
<VirtualHost *:443>
DocumentRoot "C:/xampp/htdocs/"
ServerName www.mywebsite.com
SSLEngine on
SSLCertificateFile "conf/ssl.crt/mywebsite_com.crt"
# SSLCertificateKeyFile "conf/ssl.key/server.key"
SSLCertificateKeyFile "C:/xampp/apache/bin/server.key"
<Directory "C:/xampp/htdocs/">
Options All
AllowOverride All
Require all granted
</Directory>
ProxyPass /t/request https://localhost:3000
ProxyPassReverse /t/request https://localhost:3000
</VirtualHost>
I am building an application with the help of Angular6 and facing problems in routing. All the routes are working when I click on a particular tab but whenever I refresh the current page, it is throwing 404 error. I have seen many posts regarding this issue on Stack overflow but failed to overcome from this problem.
Below is my app.module.ts
import {BrowserModule} from '#angular/platform-browser';
import {NgModule} from '#angular/core';
import {RouterModule, Routes} from '#angular/router';
import {AppComponent} from './app.component';
import {FetchApiComponent} from './fetch-api/fetch-api.component';
import {FormsModule} from '#angular/forms';
import {HttpClientModule} from '#angular/common/http';
import {UserServiceLatest} from './fetch-latest/app.service';
import {UserServiceTop} from './fetch-top/app.service';
import {YoutubePlayerModule} from 'ngx-youtube-player';
import {SidebarComponent} from './sidebar/sidebar.component';
import {FetchLatestComponent} from './fetch-latest/fetch-latest.component';
import { FetchTopComponent } from './fetch-top/fetch-top.component'
import {UserService} from './fetch-api/app.service';
import { ServiceWorkerModule } from '#angular/service-worker';
import { environment } from '../environments/environment';
import { AngularFireModule } from 'angularfire2';
import * as firebase from 'firebase';
import { firebaseConfig } from './../environments/firebase.config';
import { AngularFireDatabaseModule } from 'angularfire2/database';
import {PushService} from './push.service';
const appRoutes: Routes = [
{
path: '',
component: FetchApiComponent
},
{
path: '/latest',
component: FetchLatestComponent
},
{
path: '/top',
component: FetchTopComponent
},
{
path :'*',
component: FetchApiComponent
}
];
firebase.initializeApp(firebaseConfig);
#NgModule({
declarations: [
AppComponent,
FetchApiComponent,SidebarComponent, FetchLatestComponent, FetchTopComponent
],
imports: [
RouterModule.forRoot(appRoutes),
BrowserModule, YoutubePlayerModule,
FormsModule,
AngularFireModule.initializeApp(firebaseConfig),
AngularFireDatabaseModule,environment.production ?ServiceWorkerModule.register('firebase-messaging-sw.js'):[],ServiceWorkerModule.register('/firebase-messaging-sw.js', { enabled: environment.production }),
HttpClientModule,environment.production ? ServiceWorkerModule.register('ngsw-worker.js') : [], ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production })
],
providers: [UserService,UserServiceTop,UserServiceLatest,PushService],
bootstrap: [AppComponent]
})
export class AppModule {}
Can you point me in right direction?
You will see in your example url, that once you get the 404 error you can't make it work, but if you include a hash before the angular-specific url like /#latest it will work.
Why stops working when refreshing? your webserver is intercepting the GET request from your browser and is trying to go directly to the directory /latest, which doesn't exist. It doesn't know that it needs to go to /bosv2, find an angular app, and then add the small ending bit to your path which is a not-real directory but a routing for angular. In your local it would work as when you are doing ng serve, webpack webserver is prepared for this, but not the host where you are hosting the app.
By default, angular is using HTML5 style navigation, but with your current webserver settings you would need the old angularjs style (with hash#).
From here, you have two solutions:
Change your webserver configuration
Tell Angular to use HashLocationStrategy (perfectly valid solution), you can go old-school with the HashLocationStrategy by providing the useHash: true in an object as the second argument of the RouterModule.forRoot in the AppModule.
#NgModule({
imports: [
...
RouterModule.forRoot(routes, { useHash: true }) // .../#/latest/
],
...
I would say going the hash style has a couple of downsides, which may not be relevant in your scenario:
It doesn't produce the clean and SEO Friendly URLs that are easier for users to understand and remember.
You can't take advantage of the server-side rendering.
Hope you find this answer helpful :)
To avoid using hashed routes, you must edit your webserver configuration properly, which is the best solution. You just have to configure it so it fallbacks to index.html, which is Angular's bootstrap. Although there is no universal configuration for this, here are some:
Apache
Add a rewrite rule to .htaccess file
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
Nginx
Use try_files in your location block
try_files $uri $uri/ /index.html;
IIS
Add a rewrite rule to web.config
<system.webServer>
<rewrite>
<rules>
<rule name="Angular Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
GitHub Pages
You can't configure it directly, but you can add a 404 page. Copy index.html into 404.html in the same directory or add a symlink: ln -s index.html 404.html.
Firebase hosting
Add a rewrite rule.
"rewrites": [ {
"source": "**",
"destination": "/index.html"
} ]
Source: https://angular.io/guide/deployment#server-configuration
With .htaccess you can try with following way also:
<IfModule mod_rewrite.c>
RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html
# to allow html5 state links
RewriteRule ^ index.html [L]
</IfModule>
In app.module.ts
import {LocationStrategy, HashLocationStrategy} from '#angular/common';
After import add following line to providers.
{provide: LocationStrategy, useClass: HashLocationStrategy}
ex:
providers: [AuthService,
AuthGuard,
FlxUiDataTable,
{provide: LocationStrategy, useClass: HashLocationStrategy}]
This will solve your issue. Read Documentation here.
Add .htaccess file to your src folder.
.htaccess file
<IfModule mod_rewrite.c>
RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html
# to allow html5 state links
RewriteRule ^ index.html [L]
</IfModule>
Load .htaccess file in your build directory dist by adding it to assets in angular.json
"assets": [
"src/favicon.ico",
"src/assets",
"src/.htaccess"
],
I think you are getting 404 because your are requesting http://localhost/route which doesn't exist on tomcat server. As Angular 2 uses html 5 routing by default rather than using hashes at the end of the URL, refreshing the page looks like a request for a different resource.
When using angular routing on tomcat you need to make sure that your server will map all routes in your app to your main index.html while refreshing the page. There are multiple way to resolve this issue. Whichever one suits you you can go for that.
1) Put below code in web.xml of your deployment folder :
<error-page>
<error-code>404</error-code>
<location>/index.html</location>
</error-page>
2) You can also try using HashLocationStrategy with # in the URL for routes :
Try using:
RouterModule.forRoot(routes, { useHash: true })
Instead of:
RouterModule.forRoot(routes)
With HashLocationStrategy your urls gonna be like:
http://localhost/#/route
3) Tomcat URL Rewrite Valve : Re-write the url's using a server level configuration to redirect to index.html if the resource is not found.
3.1) Inside META-INF folder create a file context.xml and copy the below context inside it.
<? xml version='1.0' encoding='utf-8'?>
<Context>
<Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
</Context>
3.2) Inside WEB-INF, create file rewrite.config(this file contain the rule for URL Rewriting and used by tomcat for URL rewriting). Inside rewrite.config, copy the below content:
RewriteCond %{SERVLET_PATH} !-f
RewriteRule ^/(.*)$ /index.html [L]
Starting with Apache 2.4, you can use the FallbackResource directive instead of rewriting, so it will look like:
FallbackResource /index.html
If you have a different base href (say, /awesomeapp), change it for:
<Location /awesomeapp>
FallbackResource /awesomeapp/index.html
</Location>
If you are using cpanel then it is easy to solve this issue.
Go to Advanced Options
Step 1: Go to Error Pages.
Step 2: Copy your index.html code and paste it in 404.shtml.
That's it technically all your routes are redirected to index.html file. That's what angular wants :) and everything will work normal.
Here are some reference links
Namecheap Error Page Config
Godaddy Error Page config
In my case i did following thing
Method 1 :
in your app.module.ts import below thing
import { HashLocationStrategy, LocationStrategy } from '#angular/common';
#NgModule({
declarations: [...],
imports: [...],
providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}],
bootstrap: [AppComponent]
})
and build with
ng build --base-href /[PROJECT_NAME]/
method 2 :
for nginx,
nano /etc/nginx/sites-available/default
add follwing line in location block
location /[PROJECT_NAME] {
try_files $uri $uri/ /[PROJECT_NAME]/index.html;
}
sudo service nginx restart
and build with
ng build --base-href /[PROJECT_NAME]/
Refetch data on same URL navigation
imports: [RouterModule.forRoot(routes, {
onSameUrlNavigation: 'reload' })],
Make an .htaccess file and add this code; routes will start working:
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteRule ^ /index.html
how to remove ? in url yii2?
in rule :
'rules' => [
'<alias:\w+>' => 'site/<alias>',
],
in .htaccess
RewriteEngine on
# If a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward it to index.php
RewriteRule . index.php
Try this set of rules:
'<alias:\w+>/<id:\d+>' => 'site/<alias>',
'<alias:\w+>' => 'site/<alias>',
Now, my website's url looks like this because I'm using the approach described here
http://localhost:4200/#/cadastro
Is it possible to remove the hash in the url and not get the 404 error?
EDIT: Router Module added
const appRoutes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'cadastro', component: CadastroNoivosComponent },
{ path: '**', component: HomeComponent }
];
export const routing = RouterModule.forRoot(appRoutes);
If you are using Angular final, the reasons to the hash could be:
RouterModule.forRoot(yourRoutesHere, { useHash: true })
So by removing that could help.
RouterModule.forRoot(yourRoutesHere)
Alternatively if you in your providers (in NgModule) have used:
{provide: LocationStrategy, useClass: HashLocationStrategy}
just remove that.
EDIT, if you need LocationStrategy, try changing HashLocationStrategy to PathLocationStrategy:
{provide: LocationStrategy, useClass: PathLocationStrategy}
More about LocationStrategy here
Now that I have seen your routes as well regarding your 404 issue, you could try changing the following
{ path: '**', component: HomeComponent }
to:
{ path: '**', redirectTo: '', pathMatch: 'full' }
More about routing here
Also check that in your index.html you have set the basehref like so:
<base href="/">
If you use PathLocationStrategy as describe here you can remove the hash in the URL.
But getting rid of 404 error needs some server side tweak. A quick and easy way is to configure your server to load the home page when any URL of the form http://yourhost/* is requested.
Create a .htaccess file Paste the following Code And Upload on your prod Server.
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
How to set index.html for the domain name e.g. https://www.example.com/ - leads user to index.html in root directory.
I've tried different things like:
server {
# some configs
location = / {
index index.html;
fastcgi_index index.html;
}
or
location / {
index index.html;
fastcgi_index index.html;
}
}
Nothing helped me.
There are some other configs with location keyword, though I'd commented them either.
Other "location" configs in the server { clause:
location ~ .*(css|htc|js|bmp|jp?g|gif|ico|cur|png|swf|htm?|html)$ {
access_log off;
root $www_root;
}
location ~ \.php$
{
include /etc/nginx/fastcgi_params;
index index.html;
fastcgi_index index.html;
fastcgi_param SCRIPT_FILENAME $www_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass 127.0.0.1:9000;
# Директива определяет что ответы FastCGI-сервера с кодом больше или равные 400
# перенаправлять на обработку nginx'у с помощью директивы error_page
fastcgi_intercept_errors on;
break;
}
location ~ /\.ht {
deny all;
}
All them were commented and uncommented, but nothing helped.
PS Editions were made in /etc/nginx/sites-enabled/domainname.com file.
in your location block you can do:
location / {
try_files $uri $uri/index.html;
}
which will tell ngingx to look for a file with the exact name given first, and if none such file is found it will try uri/index.html. So if a request for https://www.example.com/ comes it it would look for an exact file match first, and not finding that would then check for index.html
location / { is the most general location (with location {). It will match anything, AFAIU. I doubt that it would be useful to have location / { index index.html; } because of a lot of duplicate content for every subdirectory of your site.
The approach with
try_files $uri $uri/index.html index.html;
is bad, as mentioned in a comment above, because it returns index.html for pages which should not exist on your site (any possible $uri will end up in that).
Also, as mentioned in an answer above, there is an internal redirect in the last argument of try_files.
Your approach
location = / {
index index.html;
is also bad, since index makes an internal redirect too. In case you want that, you should be able to handle that in a specific location. Create e.g.
location = /index.html {
as was proposed here. But then you will have a working link http://example.org/index.html, which may be not desired. Another variant, which I use, is:
root /www/my-root;
# http://example.org
# = means exact location
location = / {
try_files /index.html =404;
}
# disable http://example.org/index as a duplicate content
location = /index { return 404; }
# This is a general location.
# (e.g. http://example.org/contacts <- contacts.html)
location / {
# use fastcgi or whatever you need here
# return 404 if doesn't exist
try_files $uri.html =404;
}
P.S. It's extremely easy to debug nginx (if your binary allows that). Just add into the server { block:
error_log /var/log/nginx/debug.log debug;
and see there all internal redirects etc.
The answer is to place the root dir to the location directives:
root /srv/www/ducklington.org/public_html;
According to the documentation
Checks the existence of files in the specified order and uses the first found file for request processing; the processing is performed in the current context. The path to a file is constructed from the file parameter according to the root and alias directives. It is possible to check directory’s existence by specifying a slash at the end of a name, e.g. “$uri/”. If none of the files were found, an internal redirect to the uri specified in the last parameter is made. Important
an internal redirect to the uri specified in the last parameter is
made.
So in last parameter you should add your page or code if first two parameters returns false.
location / {
try_files $uri $uri/index.html index.html;
}
Add this to the location block in nginx works for me
try_files $uri $uri/ /index.html =404;
thats the entire block
location / {
expires -1;
add_header Pragma "no-cache";
add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
root /var/www
try_files $uri $uri/ /index.html =404;
}
For me, the try_files directive in the (currently most voted) answer https://stackoverflow.com/a/11957896/608359 led to rewrite cycles,
*173 rewrite or internal redirection cycle while internally redirecting
I had better luck with the index directive. Note that I used a forward slash before the name, which might or might not be what you want.
server {
listen 443 ssl;
server_name example.com;
root /home/dclo/example;
index /index.html;
error_page 404 /index.html;
# ... ssl configuration
}
In this case, I wanted all paths to lead to /index.html, including when returning a 404.