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

Angular向NodeJS发POST请求报JSON位置0意外标记解析错误

问题原因

你遇到的两个异常本质是Angular HttpClient 序列化逻辑和Express body-parser 解析规则不匹配导致的,对应两个场景的问题:

  • 不调用JSON.stringify直接传字符串this.keyword时:HttpClient检测到请求体是原始字符串类型,会自动把Content-Type设为text/plain,而你后端的bodyParser.json()只会解析Content-Type为application/json的请求,不会处理文本类型请求体,自然拿到的req.body是undefined。
  • 手动调用JSON.stringify(this.keyword)时报JSON解析错误:假设你输入的关键词是test,JSON.stringify("test")会得到带双引号包裹的字符串"test",此时你手动强制设置Content-Type: application/json,但HttpClient不会对已经是字符串类型的请求体做二次校验和格式修正,实际发出去的请求体存在引号转义偏差,body-parser解析时第一个读到的字符就是多余的双引号,直接触发Unexpected token " in JSON at position 0报错。
  • 额外隐患:你当前Express服务的CORS中间件注册在body-parser之后,也没有单独处理OPTIONS预检请求,后续很容易触发跨域拦截问题。
修复步骤

1. 调整Angular端请求代码

HttpClient本身内置了JSON序列化能力,只要你传的请求体是普通对象,它会自动完成序列化、自动设置正确的Content-Type请求头,不需要你手动调用JSON.stringify、也不需要手动设置Content-Type:

export class SearchComponent {
  constructor(private http: HttpClient) {}

  newWord = '';
  keyword = '';

  onClick() {
    const headers = new HttpHeaders()
      .set('Authorization', 'my-auth-token');

    // 直接传对象参数,不要手动做JSON序列化
    this.http
      .post('http://localhost:3000/search', {
        keyword: this.keyword
      }, {
        responseType: 'text',
        headers: headers
      })
      .subscribe((data) => {
        this.newWord = data;
      });
  }
}

2. 调整Express端代码顺序

CORS相关的响应头配置必须放在所有中间件、路由注册之前,同时单独处理OPTIONS预检请求,避免跨域异常:

const bodyParser = require("body-parser");
const express = require("express");
const app = express();

// CORS配置移到最顶部
app.all("/*", function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
  res.header(
    "Access-Control-Allow-Headers",
    "Content-Type, Authorization, Content-Length, X-Requested-With"
  );
  // 预检请求直接返回200,不需要往下走解析逻辑
  if (req.method === "OPTIONS") {
    return res.sendStatus(200);
  }
  next();
});

// CORS配置完成后再注册bodyParser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.listen(3000, () => {
  console.log("Server is running on port 3000");
});

app.post("/search", (req, res) => {
  // 此时req.body就是前端传的 { keyword: "你输入的内容" } 格式
  console.log("接收到的参数:", req.body);
  res.send(req.body.keyword);  
});

修改完成后重启Node服务,再触发请求就可以正常传参、接收返回,不会再出现JSON解析报错或者req.body为undefined的问题。

内容的提问来源于stack exchange,提问作者OutOfBounds

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:30:08