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

React应用中GET请求无法获取自定义Express API数据的原因?

React前端无法访问Cyclic.sh部署的Express API

问题背景

我正在开发一个MERN Web应用:

  • Node.js服务器部署在Cyclic.sh上,通过Express API从MongoDB获取数据,浏览器直接访问API能得到预期响应:
    [{"_id":"6436561b7adc14205dd193ce","title":"Sons Of Anarchy","body":"Body text goes here...","__v":0},{"_id":"6436561b7adc14205dd193cf","title":"Games of Thrones","body":"Body text goes here...","__v":0}]
    
  • Netlify上部署的React前端,请求该自定义API时无任何响应,但替换为公开API(如https://opentdb.com/api.php?amount=1&type=multiple)就能正常工作。尝试使用no-cors模式也无法解决问题。

相关代码

Express服务器index.js

require('dotenv').config();

const express = require('express')
const mongoose = require('mongoose')
const Book = require("./models/books");

const app = express()
const PORT = process.env.PORT || 3000

mongoose.set('strictQuery', false);
const connectDB = async () => {
  try {
    const conn = await mongoose.connect(process.env.MONGO_URI);
    console.log(`MongoDB Connected: ${conn.connection.host}`);
  } catch (error) {
    console.log(error);
    process.exit(1);
  }
}

//Routes go here
app.get('/', (req,res) => {
    res.send({ title: 'Books' });
})

app.get('/books', async (req,res)=> {
  const book = await Book.find();
  if (book) {
    res.json(book)
  } else {
    res.send("Something went wrong.");
  }
});

app.get('/add-note', async (req,res) => {
  try {
    await Book.insertMany([
      {
        title: "Sons Of Anarchy",
        body: "Body text goes here...",
      },
      {
        title: "Games of Thrones",
        body: "Body text goes here...",
      }
    ]);
    res.json({"Data":"Added"})
  } catch (error) {
    console.log("err", + error);
  }
})

//Connect to the database before listening
connectDB().then(() => {
    app.listen(PORT, () => {
        console.log("listening for requests");
    })
})

models/books.js

const mongoose = require('mongoose');

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

module.exports = mongoose.model('Book', BookSchema);

React前端App.js

import React, { useState, useEffect } from "react";
import axios from "axios";
import './App.css';

function App() {
  
  const [question, setQuestion] = useState("");
  
  const fetchQuestion = () => {
    setQuestion("");
    
    axios
      .get('https://[expressApiUrlCyclic]/books')
      .then((response) => {
        let returnQuestion = response;
        setQuestion(returnQuestion);
                          }
      )
  
  }
            
  useEffect(() => {
    fetchQuestion();
  }, []);
  
  
  return (
    <div className="App">
      <header className="App-header">
        <h1>hello</h1>
        <h1>{JSON.stringify(question)}</h1>
      </header>

      <p>text</p>

    </div>
  );
}

export default App;

原因分析

核心问题是CORS跨域限制:

  • 浏览器直接访问API属于地址栏发起的简单请求,不受同源策略限制;
  • React前端是从Netlify域名发起的AJAX请求,属于跨域请求,而你的Express服务器没有配置CORS响应头,浏览器会拦截服务器返回的响应;
  • 使用no-cors模式时,浏览器会禁止读取响应内容,因此依然无法获取数据。

解决方案

1. 为Express服务器配置CORS中间件

这是最直接的解决方法:

  • 首先安装cors包:
    npm install cors
    
  • 在Express的index.js中引入并使用该中间件(要放在路由定义之前):
    const cors = require('cors');
    // 允许所有域名跨域请求
    app.use(cors());
    

可选:限制特定域名访问(更安全)

如果只希望你的Netlify前端能访问API,可以配置指定origin:

app.use(cors({
  origin: 'https://your-netlify-frontend-domain.netlify.app' // 替换为你的前端实际域名
}));

2. 修复React前端代码的小问题

当前代码中,你把整个axios响应对象存入了状态,但实际需要的是响应体response.data,同时建议添加错误捕获以便排查问题:

const fetchQuestion = () => {
  setQuestion("");
  
  axios
    .get('https://[expressApiUrlCyclic]/books')
    .then((response) => {
      setQuestion(response.data); // 仅存储响应数据
    })
    .catch(err => {
      console.error('API请求失败:', err); // 捕获并打印错误
    })
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:34:55