我有一个Angular服务器和一个单独的Node / Express服务器,它们在同一台Vagrant Ubuntu计算机中运行。我正在学习this课程。之所以要移至另一台机器,是因为运行MongoDB客户端的Windows操作系统在连接到Mongo地图集上的数据库时遇到问题,并且因为我更习惯于Unix / Linux开发(我的另一台机器) ,对于我的品味来说,我4年前购买的Mac Mini并不太慢)。
这是我的Vagrantfile
Vagrant.configure("2") do |config|
# Running standard Ubuntu 64 bits version
config.vm.box = "ubuntu/trusty64"
# Open ports for Node.js and MongoDB
config.vm.network "forwarded_port", guest: 3000, host: 3333 # Node.js
config.vm.network "forwarded_port", guest: 27017, host: 27017 # MongoDB
config.vm.network "forwarded_port", guest: 4200, host: 4200 #
# Create a private network, which allows host-only access to the machine
# using a specific IP.
config.vm.network "private_network", ip: "192.168.33.10"
# Set up a synced folder/
config.vm.synced_folder "D:/Code/mean-apps", "/project"
# Provision VM only once
config.vm.provision :shell, :path => "provision.sh"
end
这是本课程提供的我的server.js文件
const app = require("./backend/app");
const debug = require("debug")("node-angular");
const http = require("http");
const normalizePort = val => {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
};
const onError = error => {
if (error.syscall !== "listen") {
throw error;
}
const bind = typeof port === "stri`ng" ? "pipe " + port : "port " + port;
switch (error.code) {
case "EACCES":
console.error(bind + " requires elevated privileges");
process.exit(1);
break;
case "EADDRINUSE":
console.error(bind + " is already in use");
process.exit(1);
break;
default:
throw error;
}
};
const onListening = () => {
const addr = server.address();
const bind = typeof port === "string" ? "pipe " + port : "port " + port;
debug("Listening on " + bind);
};
const port = normalizePort(process.env.PORT || "3000");
app.set("port", port);
const server = http.createServer(app);
server.on("error", onError);
server.on("listening", onListening);
server.listen(port);
这是我连接Angular和Node服务器的Angular服务
import { Post } from './posts.model';
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { stringify } from 'querystring';
@Injectable({providedIn: 'root'})
export class PostsService {
private posts: Post[] = [];
private postsUpdated = new Subject<Post[]>();
constructor(private http: HttpClient) {
}
getPosts() {
this.http.get<{message: string, posts: Post[]}>("http://0.0.0.0:3000/api/posts").subscribe((postData) => {
this.posts = postData.posts;
this.postsUpdated.next([...this.posts]);
});
}
getPostsUpdateListner() {
return this.postsUpdated.asObservable();
}
addPost(title: string, content: string) {
const post: Post = {id: null, title: title, content: content}
this.http.post<{message: string}>('http://0.0.0.0:3000/api/posts', post).subscribe((responseData) => {
this.posts.push(post);
this.postsUpdated.next([...this.posts]);
})
}
}
这是我的app.js文件
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const Post = require('./models/post');
const app = express();
mongoose.connect("mongodb+srv://postproject:[email protected]/test?retryWrites=true&w=majority", { useNewUrlParser: true,useUnifiedTopology: true }).then(() => {
console.log('Connected to database!');
}).catch(() => {
console.log('COnnection failed!');
});
app.use(bodyParser.json());
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers',
'Origin, X-Request-With, Content-Type, Accept');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PATCH, DELETE, OPTIONS');
next();
});
//
app.post('/api/posts', (req, res, next) => {
const post = new Post({
title: req.body.title,
content: req.body.content
});
post.save();
console.log(post);
res.status(201).json({
message: 'Post added sucessfully'
});
});
app.use('/api/posts', (req, res, next) => {
const posts = [
{ 'id': 'dsfdg', 'title': 'Post title from Express', 'content': 'This is coming from the server'},
{ 'id': 'gfhjtfgh', 'title': 'Second title from Express', 'content': 'ZThis is coming from the server again'},
{ 'id': 'dsfgfhdg', 'title': 'Third title from Express', 'content': 'ZThis is coming from the server yet again'},
];
res.status(200).json({
message: 'Posts fetched successfully',
posts: posts
});
});
module.exports = app;
按现在的样子,当我打开http://192.168.10.33:4200时,api中的帖子未出现在列表中(我看到我的帖子还没有消息,所以Angular没有加载我的API。
如果有必要,我将使用速度较慢的计算机,但由于我在Windows计算机上进行日常工作,因此我更喜欢以这种方式进行操作。
感谢您的帮助。
我忘记了Angular在浏览器中运行。我这边的愚蠢错误
由于Angular在主机上运行,所以我的服务应如下所示:
import { Post } from './posts.model';
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { stringify } from 'querystring';
@Injectable({providedIn: 'root'})
export class PostsService {
private posts: Post[] = [];
private postsUpdated = new Subject<Post[]>();
constructor(private http: HttpClient) {
}
getPosts() {
this.http.get<{message: string, posts: Post[]}>("http://192.168.33.10:3000/api/posts").subscribe((postData) => {
this.posts = postData.posts;
this.postsUpdated.next([...this.posts]);
});
}
getPostsUpdateListner() {
return this.postsUpdated.asObservable();
}
addPost(title: string, content: string) {
const post: Post = {id: null, title: title, content: content}
this.http.post<{message: string}>('http://192.168.33.10:3000/api/posts', post).subscribe((responseData) => {
this.posts.push(post);
this.postsUpdated.next([...this.posts]);
});
}
}