Search code examples
angularjsexpressangular-ui-routerloopback

loopback angular 404 on refresh page


I have create an application with loopback and angular but i have a problem. When i refresh the browser loopback give me a 404 url not Found.

Added base tag to index.html

<base href="/"/>

Set middlelware.json properly to serve static content:

"files": {
"loopback#static": {
  "params": "$!../client"
}

Set HTML5 mode in angular router (I'm using ui-router)

$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise('/'); 

I have yet deleted root.js from the project.

What i'm doing wrong? Thanks in advance


Solution

  • When you have enabled html5 mode/ push state mode ON in angularjs, this is a common scenario which your server should handle. If I understood your problem correctly, server returns 404 when you refresh the page which otherwise render fine if navigated from landing page. Let me know if this is the scenario:

    • Angular app lands into Home screen, say your_domain/
    • Navigate to some other page - your_domain/somepage (which will be your_domain/#somepage in case of hash bang mode)
    • Refresh the page -> throws 404

    If the scenario which you face is like given above, then this is what happens:

    • Loads the home page -> angular is bootstraped and routing is set up
    • Navigates to "somepage" -> angular route handles this and show "somepage"
    • Refresh the page -> request hits the server and requests for your_domain/somepage - which is not available in server
    • server returns 404

    How to handle this? Do Url rewrite back to your_domain/ from server in case of 404. This will bootstrap the angular app and angular route will handle the request

    More details here - https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode

    Copy pasting from above website

    Apache Rewrites

    <VirtualHost *:80>
        ServerName my-app
    
        DocumentRoot /path/to/app
    
        <Directory /path/to/app>
            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]
        </Directory>
    </VirtualHost>
    

    Nginx Rewrites

    server {
        server_name my-app;
    
        root /path/to/app;
    
        location / {
            try_files $uri $uri/ /index.html;
        }
    }
    

    Azure IIS Rewrites

    <system.webServer>
      <rewrite>
        <rules> 
          <rule name="Main Rule" 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="/" />
          </rule>
        </rules>
      </rewrite>
    </system.webServer>
    

    Express Rewrites

    var express = require('express');
    var app = express();
    
    app.use('/js', express.static(__dirname + '/js'));
    app.use('/dist', express.static(__dirname + '/../dist'));
    app.use('/css', express.static(__dirname + '/css'));
    app.use('/partials', express.static(__dirname + '/partials'));
    
    app.all('/*', function(req, res, next) {
        // Just send the index.html for other files to support HTML5Mode
        res.sendFile('index.html', { root: __dirname });
    });
    
    app.listen(3006); //the port you want to use
    

    ASP.Net C# Rewrites

    In Global.asax

    private const string ROOT_DOCUMENT = "/default.aspx";
    
    protected void Application_BeginRequest( Object sender, EventArgs e )
    {
        string url = Request.Url.LocalPath;
        if ( !System.IO.File.Exists( Context.Server.MapPath( url ) ) )
            Context.RewritePath( ROOT_DOCUMENT );
    }