You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 11:10:48