0

I am building a SPA with Angular 8.0.0. I am running into the exact same issue as described in this Github issue. Note that there is another related SO question with no accepted answer.

None of the suggested workarounds in the GitHub issue have worked for me. The Angular team has closed the issue and suggested posting a SO question.

Background

The app works initially when loading the root route http://localhost:4200/ The app redirects to /records/list which works correctly.

When navigating to other routes in the application by clicking on [routerLink] links, it works with no issues. For example, clicking on this link generated by [routerLink] works:

http://localhost:4200/record/Item?RecordID=1

<a
  [routerLink]="/record/Item]]"
  [queryParams]="{RecordID: id}"
  queryParamsHandling="merge"
>
  {{ id }}
</a>

However, when reloading the page OR typing the link directly into the browser (without clicking on a routerlink) the app does NOT load and this error message appears.

Note: The problem happens with both ng serve in the dev environment and ng build on the web server. The problem only happens on initial load with ng serve, but it happens on any page reload or direct navigation on the ng build web server. I am using a minimal express app to run the web server and I might experiment with using nginx instead.

The browser just shows a blank screen with the error message: Cannot GET /record/Item/detail

Console error:

Refused to load the image 'http://localhost:4200/favicon.ico' because it violates the following Content Security Policy directive: "default-src 'none'". Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.

Here is the Angular routing module:

app-routing.module.this

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { RecordsTableComponent } from './components/records/table/records-table/records-table.component';
import { RecordLandingComponent } from './components/records/landing/record-landing/record-landing.component';
import { RecordDetailComponent } from './components/records/detail/record-detail/record-detail.component';
import { RecordStatusComponent } from './components/records/status/record-status/record-status.component';
import { RecordProposalComponent } from './components/records/proposal/record-proposal/record-proposal.component';
import { RecordsSearchComponent } from './components/records/search/records-search/records-search.component';
import { RecordChangesGuard } from './guards/records/record-changes/record-changes.guard';
import { RecordParamsGuard } from './guards/records/record-params/record-params.guard';

const routes: Routes = [
  { path: 'records/list', component: RecordsTableComponent },
  { path: 'records/search', component: RecordsSearchComponent },
  {
    path: 'record/:RecordType',
    component: RecordLandingComponent, canActivate: [RecordParamsGuard],
    children: [
      { path: '', redirectTo: 'detail', pathMatch: 'full' },
      { path: 'new', component: RecordDetailComponent, canDeactivate: [RecordChangesGuard] },
      { path: 'detail', component: RecordDetailComponent, canDeactivate: [RecordChangesGuard] },
      { path: 'status', component: RecordStatusComponent },
      { path: 'proposal', component: RecordProposalComponent },
    ]
  },
  { path: '**', redirectTo: '/records/list' },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
pengz
  • 2,279
  • 3
  • 48
  • 91
  • 1
    does this occur on ng serve or after starting server for build project if for buil project what are you using for running server – Xesenix Aug 09 '19 at 19:42
  • @Xesenix this happens on both ng serve in the dev environment and after ng build on the web server. I am using a minimal express app to run the web server. I might experiment with trying an nginx web server to see if that makes any difference. – pengz Aug 09 '19 at 19:43
  • @Xesenix Actually, to clarify, the problem only happens on initial load with ng serve, but it happens on any page reload or direct navigation on the ng build web server. – pengz Aug 09 '19 at 19:57
  • 1
    if you see blank page after manual navigation to some route or reloading page that usualy means your server isnt redirecting calls to your /index.html this misconfiguration usually occurs on custom servers so i wonder what is wrong with your ng serve. Either way on custom server you just need redirect all none static files routes to index.html i need to lookup solution for ng serve – Xesenix Aug 09 '19 at 20:09
  • @Xesenix Thanks, I think I got it by making updates to the app.js file. Feel free to leave a quick answer and I'll mark it as correct. – pengz Aug 09 '19 at 20:23

2 Answers2

0

A big thanks to @Xesenix for pointing out that the problem may be caused by the custom server. I made some adjustments to the express server I am using to serve the angular distribution created by ng build. The server appears to be working now pending more thorough testing. Here is the updated app.js.

const express = require('express');
const http = require('http');
const app = express();

// Set name of directory where angular distribution files are stored
const dist = 'dist';

// Set port
const port = process.env.PORT || 4201;

// Serve static assets
app.get('*.*', express.static(dist, { maxAge: '1y' }));

// Serve application paths
app.all('*', function (req, res) {
  res.status(200).sendFile(`/`, { root: dist });
});

// Create server to listen for connections
const server = http.createServer(app);
server.listen(port, () => console.log("Node Express server for " + app.name + " listening on port " + port));
pengz
  • 2,279
  • 3
  • 48
  • 91
0

In your index.html add a meta tag in the head

`<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: http://localhost:4200;>`
srlgrg
  • 71
  • 4