【问题标题】:Manual refresh causes only JSON to show手动刷新只会显示 JSON
【发布时间】:2018-04-16 03:09:18
【问题描述】:

我正在使用 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 使用路由访问随机页面

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

【问题讨论】:

  • API 和 Angular url 路由名称应该不同
  • 您应该将所有请求转发给index.html,这样它就可以让 Angular 处理路由
  • @nmanikiran 谢谢!这解决了这个问题。随意添加它作为你的答案,所以我可以接受它作为正确的答案。

标签: mysql json node.js angular express


【解决方案1】:

所有路由都应该通过服务 index.html 来处理。一种常见的做法是将您的 json api 挂载到 /api/random 之类的前缀。 所以,如果你访问 localhost:3000/random,你的后端应该服务 index.html。然后,您的 Angular 应用程序应该对 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

另一种(更好的)方法是在您的 nodejs api 服务器前面使用 前端 http 服务器/负载平衡器,例如 NGINX。。看here

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

编辑:使用这种模式(无论使用 express 独立还是使用 nginx),您的 SPA 前端(在您使用 angular 构建的情况下)有责任处理 404 状态页面。

【讨论】:

    【解决方案2】:

    angular 的 URL 和 node API 差别很大,都是/random

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

    在您的情况下更改 API URL 的名称。 一般约定是为所有 Node.js API 加上 /api/{name} 前缀,这样可以避免此类问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-04
      • 2020-06-24
      • 1970-01-01
      • 2018-11-20
      • 1970-01-01
      • 1970-01-01
      • 2012-11-22
      相关资源
      最近更新 更多