手动刷新仅导致显示JSON

时间:2017-11-03 11:36:04

标签: mysql json node.js angular express

我使用NodeJS服务器从MySQL数据库收集数据,并将其作为JSON对象返回。

  app.get('/random', (req, res) => {
  var connection = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: '',
    database: 'test'
  });
  connection.connect((err) => {
    if(err) {
      res.send(err);
    } else {
      console.log("Connected to database!");
      connection.query("SELECT * FROM test", (err, rows) => {
        if(err) {
          res.send(err);
        } else {
          res.json(rows);
        }
      })
    }
  });
})

手动输入URL(localhost:3000 / random)会导致JSON对象呈现,这不是我想要的。

但是,使用Angular(v4)路由时,它会根据我的需要呈现HTML,其中包含页眉,页脚和中间数据。重要的角度代码可以在下面看到。

random.service.ts

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class RandomService {
  constructor(private http: Http) {
    console.log('Random service initialized!');
  }

  fetchData() {
    return this.http.get('/random')
    .map(res => res.json());
  }
}

random.component.ts

import { Component, OnInit } from '@angular/core';
import { RandomService } from './random.service';
import { Random } from '../../../Random';

@Component({
  selector: 'app-random',
  templateUrl: './random.component.html',
  styleUrls: ['./random.component.css'],
  providers: [RandomService]
})
export class RandomComponent implements OnInit {

  random: Random[];

  constructor(private randomService: RandomService) {
    this.randomService.fetchData()
    .subscribe(data => {
      this.random = data;
    })
  }

  ngOnInit() {
  }

}

random.component.html

<h1>Random</h1>
<div *ngFor="let r of random">
  ID: {{ r.idtest }}
  <br>
  Column: {{ r.testcol }}
  <br>
</div>

APP-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component';
import { HomeComponent } from './components/home/home.component';
import { RandomComponent } from './components/random/random.component';

const appRoutes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'random', component: RandomComponent },
  { path: 'page-not-found', component: PageNotFoundComponent },
  { path: '**', component: PageNotFoundComponent }
];

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

app.component.html

<app-header></app-header>
<router-outlet></router-outlet>
<app-footer></app-footer>

我知道这个问题,我从不尝试通过服务器渲染Angular组件。我尝试过研究,但我似乎无法知道如何做到这一点。

TL; DR:无法弄清楚如何使用NodeJS渲染Angular组件,或找出另一种方法。

我的问题显示在图片中:

使用通过Angular 的路由访问随机页面 Angular routing

通过手动输入URL(或刷新随机页面)来访问随机页面 Entering URL manually

2 个答案:

答案 0 :(得分:1)

角度和节点API的URL差异很大,都是/random

当您直接点击URL时,节点服务器将相应地提供路由。

在您的情况下,

更改API URL的名称。 一般惯例是以这种方式为所有Node.js API添加/api/{name}前缀,以避免此类问题

答案 1 :(得分:1)

所有路线都应该通过服务index.html来处理。一种常见的做法是将json api挂载到/ api / random之类的前缀。 因此,如果您访问localhost:3000 / random,您的后端应该提供index.html。然后,您的角度应用程序应该对localhost:3000 / api / random进行api调用以检索动态数据。

可以使用 express standalone

来完成

index.js

const express = require('express');
const api = require('./api.js')
const app = express();
app.use('/public', express.static(__dirname + '/public'));
app.use('/api', api) // Very important. mount your api before the all path '/*' catch 
app.get('/*', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

app.listen(8000)

api.js

const express = require('express')
const router = express.Router()
router.get('/random' /*your random api handler*/)
module.exports = router

另一个(更好的)approch将在您的nodejs api服务器前面使用像前端http服务器/负载均衡器。。看here

OUT:另一件事:您应该只与您的数据库连接一次,通常就在http服务器引导之前。然后你应该导出你的连接对象并在你的api逻辑中使用它。为每个请求建立数据库连接将使您的应用程序过度使用。

编辑:使用此模式(如果使用express standalone或使用nginx,它并不重要),您的SPA前端(在您的情况下使用angular构建)具有处理404状态页面的责任。