I have a vue app with history mode running in tomcat. When visiting www.mywebapp.com/faq or mywebapp.com/other or ../post/99 etc it first seems to be working fine. Refreshing the page seems to be working fine aswell.
However when looking closer in the browser console i see that i got an error message.
"Failed to load resource: the server responded with a status of 404 ()"
The page is returning a 404 error for a split second before it redirects me and then the page loads.
On very slow internet connections the 404 error is there for a longer time before it loads.
Anyone know what i am missing here? I have added the following code to try to handle it but without success.
My router looks like this:
export const router = new Router({
mode: 'history',
base: '/',
routes: [
{
name: 'home',
path: '/',
component: Home
},
....,
{
path: '*',
component: ErrorLanding,
name: 'NotFound'
},
],
scrollBehavior(to, from, savedPosition) {
return {x:0, y: 0}
}
});
router.beforeEach((to, from, next) => {
const publicPages = ['/', '/login', '/register',
'/help', '/ticket', '/about' ];
const authRequired = !publicPages.includes(to.path);
const loggedIn = localStorage.getItem('user');
const redirect = to.path;
if (authRequired && loggedIn === null) {
if(to.meta.authRequired === false) {
next();
}
else
next({ name: 'Login', query: { redirect: redirect } });
} else {
next();
}
});
my vue.config.js looks like this:
module.exports = {
devServer: {
port: 80,
proxy: "http://localhost/*"
},
publicPath: process.env.NODE_ENV === 'production'
? '/'
: '/'
}
and finally, i have a web.xml file in dist/ROOT/WEB-INF/ with the following code:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"
metadata-complete="true">
<display-name>my app</display-name>
<description>
this is my app description
</description>
<error-page>
<error-code>404</error-code>
<location>/</location>
</error-page>
</web-app>
update
When i add this line of code to server.xml
<Valve
className="org.apache.catalina.valves.rewrite.RewriteValve"/>
and create a rewrite.config file that i add to Catalina/localhost/ with this info:
RewriteCond %{REQUEST_PATH} !-f
RewriteRule ^/(.*) /index.html
It is working, and i dont get any error message any more. But now i have a new issue. My arrays that are being populated via Vuex are returning infinite loops. How can this be?
Update
I have tried to add this to the rewrite.config file:
RewriteRule ^/api1/ - [L,NC]
RewriteRule ^/api2/ - [L,NC]
RewriteRule ^/api3/ - [L,NC]
RewriteRule ^/api4/ - [L,NC]
RewriteRule ^/api5/ - [L,NC]
RewriteRule ^/api6/ - [L,NC]
RewriteCond %{REQUEST_PATH} !-f
RewriteRule ^/(.*) /index.html
update SOLVED Below had to be added to the rewrite.config file.
RewriteRule ^/myapi1/.* - [L,NC]
RewriteRule ^/myapi2/.* - [L,NC]
RewriteRule ^/myapi3/.* - [L,NC]
RewriteRule ^/myapi4/.* - [L,NC]
RewriteRule ^/myapi5/.* - [L,NC]
RewriteRule ^/host-manager/.* - [L,NC]
RewriteRule ^/manager/.* - [L,NC]
RewriteCond %{REQUEST_PATH} !-f
RewriteRule ^/(.*) /index.html
Big thanks to @Michal Levy for help!!
Problem is result of using history mode of Vue Router and is very well described in the docs
When using history mode, the URL will look "normal," e.g. http://oursite.com/user/id. Here comes a problem, though: Since our app is a single page client side app, without a proper server configuration, the users will get a 404 error if they access http://oursite.com/user/id directly in their browser. To fix the issue, all you need to do is add a simple catch-all fallback route to your server. If the URL doesn't match any static assets, it should serve the same index.html page that your app lives in.
There are also lot of examples how to do it for lot of servers - not for Tomcat tho...
To configure "SPA fallback" (common name for this) in Tomcat you must:
server.xml
Edit the ~/conf/server.xml
to add the below Valve inside the Host section as below:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
</Host>
rewrite.config
Create directory structure — ~/conf/Catalina/localhost/
and create the rewrite.config
file inside it with the below content:
RewriteCond %{REQUEST_PATH} !-f
RewriteRule ^/(.*) /index.html
Note: Beware that above rewrite rule causes your server to return index.html
for any request that does not match "regular file" (see Rewrite Valve Docs). So if your server also serves some kind of API (REST for example), you need to modify rewrite rules to not to rewrite requests to API.
For example if your API is served on /api/...
, your rewrite rules should look like this:
# match any URL starting with `/api/`, do not rewrite and don't process other rules...
RewriteRule ^/api/ - [L]
RewriteCond %{REQUEST_PATH} !-f
RewriteRule ^/(.*) /index.html