无法从Angular向本地Node.js服务器发送HTTP POST请求
问题描述
我搭建了监听本地3000端口的Express Node.js服务器,用于打印接收的JSON内容,使用Postman发送请求时能正常打印JSON,但通过Angular页面点击按钮发送列表项数据时,服务器并未打印该内容,仅Postman请求有效。
服务器代码
var express = require('express'); var bodyParser = require('body-parser'); var app = express(); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()) var port = 3000; app.post('/instance', function(req, res) { const obj = JSON.parse(JSON.stringify(req.body)) console.log(obj); //res.send(req.body); }); // start the server app.listen(port); console.log('Server started! At http://localhost:' + port);
Angular HTML代码
<ng-container *ngFor="let instance of instancesList"> <tr class="col-sm border border-primary" style="color:#111111"> <td>{{instance.id}}</td> <td>{{instance.name}}</td> <td>{{instance.zone}}</td> <td>{{instance.ip}}</td> <td> <button (click)="onClick(instance)" type="button" class="btn border-primary btn-lg">test</button></td> </ng-container>
Angular组件代码
const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json', }) }; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) @Injectable({providedIn:'root'}) export class AppComponent{ instancesList = instances; baseUrl = "http://localhost:3000/instance" constructor(private http: HttpClient) { } onClick(instance: Instance) : Observable<Instance>{ const json = JSON.stringify(instance) return this.http.post<Instance>(this.baseUrl, json, httpOptions) // prints the json on the webpage just for testing alert(JSON.stringify(instance)); } }
解决方案
你的代码存在几个关键问题,逐一修正即可:
- HTTP请求未触发:Angular的HttpClient返回的是冷Observable,必须调用
.subscribe()才会实际发送请求,你的onClick方法仅返回Observable但未订阅,导致请求未发出。 - 多余的JSON序列化:HttpClient会自动将JavaScript对象序列化为JSON,手动调用
JSON.stringify()会把字符串作为请求体发送,服务器的bodyParser.json()无法正确解析该格式。 - 错误的装饰器使用:组件不需要
@Injectable装饰器,该装饰器用于服务类,移除它避免潜在问题。 - 跨域问题:Angular默认运行在4200端口,与服务器3000端口存在跨域,需添加CORS中间件。
- 服务器未返回响应:请求发送后服务器无响应,可能导致浏览器请求异常,需添加响应返回逻辑。
修正后的Angular组件代码
const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json', }) }; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent{ instancesList = instances; baseUrl = "http://localhost:3000/instance" constructor(private http: HttpClient) { } onClick(instance: Instance): void { // 直接传入对象,HttpClient自动完成JSON序列化 this.http.post<Instance>(this.baseUrl, instance, httpOptions) .subscribe({ next: (res) => console.log('请求成功', res), error: (err) => console.error('请求失败', err) }); alert(JSON.stringify(instance)); } }
修正后的服务器代码
var express = require('express'); var bodyParser = require('body-parser'); const cors = require('cors'); var app = express(); // 解决跨域问题 app.use(cors()); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()) var port = 3000; app.post('/instance', function(req, res) { // bodyParser已完成解析,无需重复处理 const obj = req.body; console.log(obj); // 返回响应,告知请求结果 res.status(200).send({ message: '数据接收成功', data: obj }); }); // start the server app.listen(port); console.log('Server started! At http://localhost:' + port);
额外步骤
安装CORS依赖:
npm install cors
完成以上修改后,点击按钮即可正常发送请求,服务器会打印接收到的JSON数据。
内容的提问来源于stack exchange,提问作者chippy2022
相关产品推荐
相关产品推荐

