语法错误:在JSON的位置0处出现意外令牌 Express。

5
我正在尝试按照此教程(https://levelup.gitconnected.com/introduction-to-express-js-a-node-js-framework-fa3dcbba3a98)连接Express和React Native。我有一个运行server.js脚本的服务器,在我的IP、端口3000上连接到客户端(App.tsx)。服务器和应用程序在同一设备上分别在不同终端中同时运行。服务器可以正常接收GET请求,因为当应用程序启动时,useEffect函数会调用一个GET请求,然后服务器发送一个消息。但是我的POST请求,其中包含设置为JSON.stringify("hello world")的内容主体,并不起作用。每当我按下按钮时,服务器脚本都会返回以下错误:
SyntaxError: Unexpected token h in JSON at position 0
    at JSON.parse (<anonymous>)
...

我猜想我发送的json格式不正确,或者没有正确设置内容类型,但我一直没有找到确切的问题。

App.tsx文件(其中myip是我的IP地址):

import { StatusBar } from 'expo-status-bar';
import React, { useEffect, useState } from 'react';
import { StyleSheet, Text, View, ScrollView, TouchableOpacity, TextInput } from 'react-native';

export default function App() {
  const [response, setResponse] = useState();
  useEffect(() => {
    fetch("http://myip:3000/get")
     .then(res => res.json())
     .then(res => console.log(res.theServer))
   }, []);
  

  async function handleSubmit() {
    console.log('button press');
    const response = await fetch("http://myip:3000/wow/post", {
      method: "POST",
      headers: {
      "Content-Type": "application/json"
      },
      body: JSON.stringify("hello world")
    });
  const body = await response.text();
  setResponse({ responseToPost: body });
  }

  return (
  <View style={styles.container}>
  <TouchableOpacity onPress={handleSubmit}>
     <Text>Submit</Text>
  </TouchableOpacity>
  </View>
}
...
});

server.js

const express = require("express");
const bodyParser = require("body-parser");
const app = express();
const port = process.env.PORT || 3000;


app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.get("/get", (req, res) => {
  res.send({ theServer: "hElLo FrOm YoUr ExPrEsS sErVeR" });
});
app.post("/wow/post", (req, res) => {
  console.log(req.body);
  res.send(`Here is what you sent me: ${req.body.post}`);
});
app.listen(port, () => console.log(`listening on port ${port}`));

抛出的错误是否在body-parser内部?如果不需要body-parser作为额外的中间件,也许Express尝试解析JSON两次,因此您只需要删除这行代码:app.use(bodyParser.json()); - CertainPerformance
你认为为什么req.body有一个post属性?你没有发送它。 - Bravo
1
@CertainPerformance 你仍然需要连接中间件,例如 app.use(express.json())。内置的中间件只是 body-parser 的替代品。 - Phil
2个回答

8

首先,您不再需要显式地包含body-parser。它现在已经与Express捆绑在一起,并通过以下函数可用...

app.use(express.json())
app.use(express.urlencoded()) // extended = true is the default

JSON解析中间件默认配置为处理对象。虽然像"hello world"这样的字符串文字是有效的JSON,但它不是框架期望的,因此会出现错误。

由于您似乎正在尝试访问req.body.post,因此应该使用这样的结构发送数据

fetch("http://myip:3000/wow/post", {
  method: "POST",
  headers: {
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ post: "hello world" })
})

或者,如果你确实想要发布一个JSON字符串字面量,你需要像这样配置你的JSON中间件。
app.use(express.json({ strict: false }))

strict

启用或禁用仅接受数组和对象;当禁用时将接受任何 JSON.parse 接受的内容。

在这种情况下,您的 "hello world" 字符串将出现在 req.body 中。


有点“疯狂”的是,你必须进行额外的参数配置才能使express.json()中间件接受完整的JSON规范(其中包括空字符串、数字等)。但感谢app.use(express.json({ strict: false })),解决了这个问题。 - tinkering.online

-1

对我来说,添加

  res.header('Access-Control-Allow-Origin', '*');

问题已解决


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接