Angular2 Router and Express Integration

2019-07-25 14:25发布

问题:

I'm having a problem using the Angular2 router and express, but none of the previous questions seem to have the solution I need. I'm using the latest version of the angular2-cli.

When I direct my browser to localhost:3000, I get the generic "app works" message that the angular2-cli generates. My problem arises when I try to navigate to one of my child routes, such as localhost:3000/auth/login - it redirects me back to the same "app works" page, instead of showing me a page that says "login works".

Looking at other questions on stack exchange, I figure that the issue is here:

app.get('*', (req, res) => {
      res.sendFile(path.join(__dirname, 'dist/index.html'));
    });

When I replace the * with a /, instead of redirecting me back to my target page, it gives me the cannot GET error.

In summary, my problem is that url navigation of my angular2 routes integrated into my express app is not working.

My express code in server.js is as follows:

var express = require("express");
var app = express();
var bodyParser = require("body-parser");
var mongoose = require("mongoose");
var path = require("path");

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));

app.use(express.static(path.join(__dirname, 'dist')));

// Catch all other routes and return the index file
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist/index.html'));
});

app.listen(3000, () => {
    console.log("Server has started");
});

My application's routing module is as follows (app-routing.module.ts):

import {Route, RouterModule} from '@angular/router';
import {NgModule} from '@angular/core';
import {LoginComponent} from './login/login.component';
import {RegisterComponent} from './register/register.component';
import {FeedComponent} from './feed/feed.component';
import {FindComponent} from './find/find.component';
import {SubmitComponent} from './submit/submit.component';
import {ProfileComponent} from './profile/profile.component';

export const routeConfig =  [
    {
        path: "auth",
        children: [
            {
                path: "login",
                component: LoginComponent
            },
            {
                path: "register",
                component: RegisterComponent
            },
            {
                path: "",
                redirectTo: "/login",
                pathMatch: "full"
            }

        ]
    },
    {
        path: "app",
        children: [
            {
                path: "feed",
                component: FeedComponent
            },
            {
                path: "find",
                component: FindComponent
            },
            {
                path: "submit",
                component: SubmitComponent
            },
            {
                path: "profile",
                component: ProfileComponent
            },
            {
                path: "",
                redirectTo: "/feed",
                pathMatch: "full"
            }
        ]
    }
];

@NgModule({
    imports: [RouterModule.forRoot(routeConfig)],
    exports: [RouterModule]
})
export class AppRoutingModule{

}

My application module is as follows:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import {AppRoutingModule} from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
import { RegisterComponent } from './register/register.component';
import { FeedComponent } from './feed/feed.component';
import { FindComponent } from './find/find.component';
import { SubmitComponent } from './submit/submit.component';
import { ProfileComponent } from './profile/profile.component';

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    RegisterComponent,
    FeedComponent,
    FindComponent,
    SubmitComponent,
    ProfileComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

All the components have been defined in their respective files and are the barebones default templates generated by the angular2-cli.

I have no idea what to do at this point. I've even tried restarting and rewriting this project multiple times to see if I went wrong somewhere (this is my 3rd attempt).

回答1:

For angular2 and nodejs integration you can either put this in server.js:

var cors = required('cors');
app.use(cors());

or you can make use of proxy in your web server. For example in apache2 inside virtualhost tag you can do

ProxyPass /api/ http://localhost:3000/

ProxyReverse /api/ http://localhost:3000/

Now instead of using "http://localhost:3000/" in your http request function (although you are not using it) you can use just "api/".