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

React Native+Node.js+MongoDB提交数据报错:JSON格式无效

React Native + Node.js/Express/MongoDB 提交数据报错问题排查与修复

问题背景

开发React Native前端 + Node.js+Express+MongoDB后端应用,读取MongoDB数据正常,但提交数据到数据库时前后端均报错。前端报错如图,后端报错:SyntaxError: Unexpected token 'n', "#" is not valid JSON。


前端代码

CreatePostScreen.js

import { create } from "apisauce";
const apiClient = create({
  baseURL: "My IP Address : port number",
});

const addPost= (post) => {
  const data = new FormData();
  data.append("name", post.name);
  data.append("title", post.title);

  return apiClient.post('/post/create', data);
};


const handleSubmit = async (data) => {
    const result = await addPost(data);

    if (!result.ok) return alert(result.originalError);
    alert("done");
};

<AppForm
  initialValues={{
    name: "",
    title: "",
  }}
  onSubmit={handleSubmit}
  validationSchema={validationSchema}>
    <AppFormField name={"name"} placeholder="Name" />
    <AppFormField name={"title"} placeholder="Title" />
    
    <SubmitButton title="Create Post" />
</AppForm>

AppForm.js

function AppForm({ initialValues, onSubmit, validationSchema, children }) {
  return (
    <Formik
      initialValues={initialValues}
      onSubmit={onSubmit}
      validationSchema={validationSchema}>
      {() => <>{children}</>}
    </Formik>
  );
}

AppFormField.js

function AppFormField({ name, ...otherProps }) {
  const { setFieldTouched, setFieldValue, errors, touched, values } = useFormikContext();

  return (
    <>
      <TextInput
        onChangeText={(text) => setFieldValue(name, text)}
        value={values[name]}
      />
      <ErrorMessage error={errors[name]} visible={touched[name]} />
    </>
  );
}

后端代码

postModel.js

const mongoose = require("mongoose");

const PostSchema = new mongoose.Schema({
  name: { type: String, required: true },
  title: { type: String, required: true },
});

module.exports = mongoose.model("Post", PostSchema );

postController.js

const Post = require("../models/postModel");
const mongoose = require("mongoose");
const dotenv = require("dotenv");
dotenv.config();

mongoose
  .connect(process.env.MONGO_URL)
  .then(() => console.log("db connected"))
  .catch((err) => console.log(err));

module.exports = {
  createPost: async (req, res) => {
    try {
      const p = new Post(req.body);
      const val = await p.save();
      res.status(200).json(val);
    } catch (error) {
      res.status(500).json("Failed to create a new post");
    }
  },

postRouter.js

const postController = require("../controllers/postController ");
const express = require("express");
const router = express.Router();

router.use(express.urlencoded({ extended: true }));
router.use(express.json());

router.get("/", structureController.getAllStructures);
router.get("/:id", structureController.getStructure);
router.get("/search/:key", structureController.searchStructure);

router.post("/create",postController.createPost);

index.js

const express = require("express");
const app = express();
const postRouter = require("./routers/post");

app.use("/structures", structureRouter);

app.listen(process.env.PORT, "My IP Address", () =>
  console.log(`App listening on port ${process.env.PORT}!`)
);

错误信息

  • 前端报错:
    前端错误
  • 后端报错:
SyntaxError: Unexpected token 'n', "#" is not valid JSON
    at JSON.parse (<anonymous>)
    at createStrictSyntaxError (node_modules\express\node_modules\body-parser\lib\types\json.js:160:10)
    at parse (node_modules\express\node_modules\body-parser\lib\types\json.js:83:15)
    at node_modules\body-parser\lib\read.js:128:18
    at AsyncResource.runInAsyncScope (node:async_hooks:206:9)
    at invokeCallback (node_modules\raw-body\index.js:231:16)
    at done (node_modules\raw-body\index.js:220:7)
    at IncomingMessage.onEnd (node_modules\raw-body\index.js:280:7)
    at IncomingMessage.emit (node:events:514:28)
    at endReadableNT (node:internal/streams/readable:1376:12)

问题根源及修复方案

核心问题

  1. 前端用FormData提交数据,但后端仅配置了JSON解析中间件,无法处理multipart/form-data格式,导致body-parser尝试将FormData解析为JSON,触发语法错误。
  2. 后端存在路由挂载错误、未定义控制器引用、数据库连接逻辑冗余等问题。

修复步骤

1. 前端调整:改用JSON格式提交

无需使用FormData,直接传递post对象,apisauce会自动设置正确的Content-Type:

// CreatePostScreen.js 中修改addPost函数
const addPost= (post) => {
  return apiClient.post('/post/create', post);
};

2. 后端修复路由挂载错误

index.js中路由引用与挂载路径不匹配,修正如下:

const express = require("express");
const mongoose = require("mongoose");
const dotenv = require("dotenv");
const postRouter = require("./routers/post");

dotenv.config();
const app = express();

// 全局配置请求解析中间件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 数据库连接移到入口文件
mongoose
  .connect(process.env.MONGO_URL)
  .then(() => console.log("db connected"))
  .catch((err) => console.log(err));

// 挂载post路由到正确路径
app.use("/post", postRouter);

app.listen(process.env.PORT, "My IP Address", () =>
  console.log(`App listening on port ${process.env.PORT}!`)
);

3. 后端路由文件修正引用错误

移除未定义的structureController引用,清理冗余中间件配置:

const postController = require("../controllers/postController"); // 移除末尾空格
const express = require("express");
const router = express.Router();

// 全局已配置解析中间件,此处无需重复添加
router.post("/create", postController.createPost);

module.exports = router; // 补充路由导出

4. 后端控制器优化数据库连接逻辑

移除控制器中的重复数据库连接,优化错误返回信息:

const Post = require("../models/postModel");

module.exports = {
  createPost: async (req, res) => {
    try {
      const p = new Post(req.body);
      const val = await p.save();
      res.status(200).json(val);
    } catch (error) {
      console.error(error); // 打印具体错误便于排查
      res.status(500).json({ 
        message: "Failed to create a new post", 
        error: error.message 
      });
    }
  },
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 23:55:53