【问题标题】:Making multiple requests to node.js API from React.js从 React.js 向 node.js API 发出多个请求
【发布时间】:2019-08-10 10:43:03
【问题描述】:

我目前正在开发一个应用程序,它使用 Node.js REST 后端和客户端的 React.js。

我在尝试向我的 API 发出多个 fetch 请求时遇到问题,导致请求停止,这可能需要 2 分钟或更长时间才能返回数据……我在发出单个请求时没有问题到 React 或 Postman 的后端。

我的后端“/movies/{category}”中有一个端点,它根据所选类别返回电影列表。例如

/movies/horror
/movies/thriller
/movies/comedy

在我的 React 应用中,组件结构如下:

APP
-- DASHBOARD
-- -- MOVIELIST (horror)
-- -- MOVIELIST (thriller)
-- -- MOVIELIST (comedy)

在我的每个 MOVIELIST 组件中,我都在对 /movies/{category} 进行提取以获取数据。

如果我只加载一个 MOVIELIST 组件,我没有问题。但是一旦我尝试加载多个,请求就会开始停止。

我已在 Chrome、FireFox 和 IE 中尝试过此操作,但三个都出现了问题。

以下是 chrome 中停止请求的示例:

任何帮助将不胜感激。谢谢!

-

更新:

这是我的后端的设置方式

// index.js
const express = require('express');
const router = express.Router();

const app = express();    

const movies = require('./routes/movies');

app.use(express.json());
app.use('/api/movies', movies);

const port = process.env.PORT || 5000;    
app.listen(port, () => console.log(`Listening on port ${port}...`));

然后是我的电影终点

//movies.js
const express = require('express');
const router = express.Router();
const moment = require('moment');
const sql = require('mssql');
const _ = require('lodash');

const config = require('../config/config');

//For CORS
router.options('/*', (req, res) => {
    res.header('Access-Control-Allow-Origin', "*");
    res.header('Access-Control-Allow-Methods', "GET, POST, PUT");
    res.header('Access-Control-Allow-Headers', ['Content-Type', 'x-access-token']).send();
});

router.get('/horror', auth, (req, res) => {
sql.connect(config).then(pool => {
        return pool.request().query(
            `SELECT STATEMENT`
        );
    }).then(result => {    
        sql.close();
        res.header('Access-Control-Allow-Origin', "*");
        res.header('Access-Control-Allow-Methods', "GET, POST, PUT");
        res.header('Access-Control-Allow-Headers', ['Content-Type', 'x-access-token']);
        return res.send(result);    
    }).catch(err => {
        sql.close();
        res.header('Access-Control-Allow-Origin', "*");
        res.header('Access-Control-Allow-Methods', "GET, POST, PUT");
        res.header('Access-Control-Allow-Headers', ['Content-Type', 'x-access-token']); 
        return res.send(err);
    });
})

router.get('/thriller', auth, (req, res) => {
    sql.connect(config).then(pool => {
            return pool.request().query(
                `SELECT STATEMENT`
            );
        }).then(result => {           
            sql.close();
            res.header('Access-Control-Allow-Origin', "*");
            res.header('Access-Control-Allow-Methods', "GET, POST, PUT");
            res.header('Access-Control-Allow-Headers', ['Content-Type', 'x-access-token']);
            return res.send(result);        
        }).catch(err => {
            sql.close();
            res.header('Access-Control-Allow-Origin', "*");
            res.header('Access-Control-Allow-Methods', "GET, POST, PUT");
            res.header('Access-Control-Allow-Headers', ['Content-Type', 'x-access-token']); 
            return res.send(err);
        });
    })

router.get('/comedy', auth, (req, res) => {
    sql.connect(config).then(pool => {
            return pool.request().query(
                `SELECT STATEMENT`
            );
        }).then(result => {        
            sql.close();
            res.header('Access-Control-Allow-Origin', "*");
            res.header('Access-Control-Allow-Methods', "GET, POST, PUT");
            res.header('Access-Control-Allow-Headers', ['Content-Type', 'x-access-token']);
            return res.send(result);        
        }).catch(err => {
            sql.close();
            res.header('Access-Control-Allow-Origin', "*");
            res.header('Access-Control-Allow-Methods', "GET, POST, PUT");
            res.header('Access-Control-Allow-Headers', ['Content-Type', 'x-access-token']); 
            return res.send(err);
        });
    })

module.exports = router;

【问题讨论】:

  • 这是一个设计/架构问题(很可能在后端......)不是一个简单的答案......如果你有 github 上的代码,请在此处上传链接,我会尽力提供帮助你……
  • 嘿,我已经用我的后端代码的样子编辑了我的问题。

标签: javascript node.js reactjs api fetch


【解决方案1】:

我是开发新手,所以你可能不会很认真地对待我所说的话。

我认为您在获取数据时做得太多了。您可以在仪表板中获取所有电影,但要确保所有电影都有类别,然后使用单个端点根据传递类别名称作为查询的类别来获取电影。

在仪表板中,有一个 getAllMovies 端点 -/movies/getAllMovies- 在 Home/Dashboard 组件呈现时获取所有电影。

在侧边栏/导航中为每个类别提供三个链接/按钮。创建一个端点 - /movies/categories/${category_name},对于您感兴趣的每个类别,将类别名称作为查询传递给端点并获取。

就像@SakoBu 说的把它放在github 上并分享链接。

编辑:您可以使用一个用于 cors 的 npm 包,它可以为您节省大量的击键次数并使您的代码更具可读性。

https://github.com/expressjs/cors

【讨论】:

  • 嘿,我没有使用 getAllMovies 的原因是因为单个类别的查询实际上比获取类别稍微复杂一些,而且我不想让 super特定端点只是为了在仪表板上显示某些内容。不过感谢 NPM cors 包,这肯定会让事情变得更清洁!
【解决方案2】:

通过在后端使用 async/await 已解决此问题。

router.get('/thriller', auth, (req, res) => {

     await getThrillers().then(result => {
        res.send(result);
    }).catch(err => {
        console.log(err)
    });

})

async function getThrillers(){   

    let promise = new sql.ConnectionPool(config).connect().then(pool => {
        return pool.request().query(`SELECT STATEMENT`)
    }).catch(error => {
        return error
    });

    let result = await promise;        

    return result;

}

【讨论】:

    猜你喜欢
    • 2019-11-11
    • 2014-04-16
    • 2014-09-30
    • 1970-01-01
    • 2016-11-11
    • 2015-09-10
    • 1970-01-01
    • 2017-12-08
    • 2022-10-08
    相关资源
    最近更新 更多