【问题标题】:fetch(url) in redux.js using the wrong portredux.js 中的 fetch(url) 使用错误的端口
【发布时间】:2020-07-12 16:41:42
【问题描述】:

我有一个 MERN 应用程序,它使用以下组合:

  1. Axios 的异步/等待,以及
  2. Redux

管理整个应用程序的数据流。 Redux主要用于登录+授权(along these lines)。在我的应用程序的许多页面之间共享的其他一些表是通过 redux 获取的,并且可以通过 reduxState 访问。但是,由于我的 MERN 应用程序中的大多数路由都不需要共享状态,因此我只是使用 axios 从我的 Mongo 数据库中获取大部分数据。

我目前只有 redux 提取有问题,包括登录/授权以及通过 redux 提取的所有其他表。在我的控制台中,我收到有关 redux 操作的以下错误:

应用程序的节点 API 在端口 8080 上提供服务,如果我复制此 url,更改端口,然后将 http://localhost:8080/api/cbb/teams/list 直接粘贴到我的 chrome 浏览器中,它确实会返回我所期望的数据。所以我认为端口 3000 / 8080 存在问题。端口 3000 是应用程序客户端服务的地方(我相信),我认为这就是 Redux 向端口 :3000 发出 GET 请求的原因。

我的问题是,我可以做些什么来解决/调试这个问题,以便我的 Redux 获取再次工作?我假设我只需要将 Redux 提取到正确的端口“指向”,但我不确定如何执行此操作。

编辑 1

按照this question 的行,我的client 文件(包含我的所有前端代码)位于我的节点API 目录中。在我的client/package.json 文件中,我有一行"proxy": "http://localhost:8080",

编辑 2

这是来自teams-action 的主要函数,它构建然后获取的 URL:

export function fetchTeams(team, conference) {
    return dispatch => {
        let url = '/api/cbb/teams';
        if (team) { url += '/team/' + team; }
        else if (conference) { url += '/conference/' + conference; }
        else { url += '/list'; }

        console.log('fetchTeams url: ', url);
        dispatch(fetchSportsDataBegin());
        return fetch(url)
            .then(handleErrors)
            .then(res => res.json())
            .then(json => {
                dispatch(fetchSportsDataSuccess(json));
                return json;
            })
            .catch(error => dispatch(fetchSportsDataError(error)));
    };
}

fetchCBBTeams 是从页面的主容器组件调用的。打印出来的 url 就是 /api/cbb/teams/list,因为我故意不带参数调用它

【问题讨论】:

  • 您能展示一下您是如何实际发出提取请求和构建 API URL 的吗?在第一个 Redux 链接中,他们正在使用 fetch(`${config.apiUrl}/users/authenticate`, ...) 并使用 config.apiUrl 来配置 API 源。在您发布的第二个链接中,OP 未能使用 proxy 配置来发出他们的获取请求,这就是为什么它对他们不起作用。
  • 当然,将对帖子进行编辑 - 已更新
  • return fetch(proxy + url)
  • 当我用fetch('http://localhost:8080' + url) 更新返回时,它可以工作,是的
  • 但是我不认为我想将它硬编码到我所有的 redux 操作文件中,因为那样它就不会从 prod 上的生产路径中获取,不是吗?

标签: javascript node.js reactjs redux react-redux


【解决方案1】:

这应该是您在客户端获取的数据

export function fetchTeams(team, conference) {
    return dispatch => {
        let host = "http://localhost:8080";
        let url = '/api/cbb/teams';
        if (team) { url += '/team/' + team; }
        else if (conference) { url += '/conference/' + conference; }
        else { url += '/list'; }

        console.log('fetchTeams url: ', url);
        dispatch(fetchSportsDataBegin());
        return fetch(host + url)
            .then(handleErrors)
            .then(res => res.json())
            .then(json => {
                dispatch(fetchSportsDataSuccess(json));
                return json;
            })
            .catch(error => dispatch(fetchSportsDataError(error)));
    };
}

通知let host = "http://localhost:8080";return fetch(host + url)

只调用/api/cbb/teams 客户端将获得他的主机。与应该以 http 开头的 html 中的链接相同,如果您创建链接 www.google.com 会将您发送到 domain.com/www.google.com

【讨论】:

  • 这不只适用于我的本地开发版本吗?在生产中,我希望主机是我的域 URL,而不是 localhost?
  • 其他 2 个问题可以帮助我理解这一点:(a) 通常的做法是始终在 redux 操作的 fetch 中同时包含主机 + url,并且 (b) 这不是解释为什么代理不适合我。
  • 这样不行,你可以将主机定义为全局值,但它必须在某个地方定义,否则它将使用客户端主机。
  • 关于 Q(b) 的另一件事:请记住,代理仅在开发中有效(使用 npm start),您可以确保 /api/todos 之类的 URL 指向生产中的正确做法。”create-react-app.dev/docs/proxying-api-requests-in-development
  • 我已经更新了我的答案,展示了如何使用环境变量,如 flakerimi 评论中的文档链接中所述
【解决方案2】:

您遇到了与链接问题相同的问题,same answer 将解决该问题。

如果您使用 package.json proxy 属性来配置 API 源,那么您需要找到某种方法将该值获取到您的应用程序代码中,并使用它来配置您正在生成的获取 URL。

例如,在您链接的“React Hooks + Redux - 用户注册和登录教程和示例”文章的底部,in the React Webpack Config section 它显示了他们如何配置 config.apiUrl 值以便可以使用它在他们的应用程序中。


使用 .env 文件配置 API url 的新示例

您可以使用带有create-react-app.env 文件为您的应用程序配置此类值。

这样做的好处是它是一种标准且易于理解的模式,它允许像这样轻松配置开发和生产变量。

在项目的根目录中创建一个.env 文件,以配置用于生产的 API 源:

    # .env
    REACT_APP_PROXY=http://my-production-domain-and-port:8080

然后创建一个.env.development 文件来配置你本地开发的API源:

    # .env.development
    REACT_APP_PROXY=http://localhost:8080

create-react-app 应该会自动将此文件及其变量加载到您的应用程序中(请参阅docs for details)。

然后你可以在你的应用程序中访问这个环境变量:

    // config.js
    // You can collect together any other environment variables here as well
    const apiUrl = process.env.REACT_APP_PROXY;

    export default {
        apiUrl
    }
    import config from './path-to/config';

    export function fetchTeams(team, conference) {
        return dispatch => {
            let url = `${config.apiUrl}/api/cbb/teams`;
            if (team) { url += '/team/' + team; }
            else if (conference) { url += '/conference/' + conference; }
            else { url += '/list'; }

            console.log('fetchTeams url: ', url);
            dispatch(fetchSportsDataBegin());
            return fetch(url)
                .then(handleErrors)
                .then(res => res.json())
                .then(json => {
                    dispatch(fetchSportsDataSuccess(json));
                    return json;
                })
                .catch(error => dispatch(fetchSportsDataError(error)));
        };
    }

【讨论】:

  • 我不太确定我是否曾经对webpack.config.js 文件进行过编辑。我大约 18 个月前使用 create-react-app 创建了这个应用程序,所有 webpack 的东西都已经从我这里抽象出来了。
  • 我可能已经在某个地方有一个 .env 文件,因为我之前使用过 process.env.NODE_ENV。但是,我在设置 NODE_ENV 时很难找到 - 编辑:nvm 看起来 NODE_ENV 是默认环境变量。
  • 这一切都非常有帮助。谢谢
猜你喜欢
  • 2021-01-18
  • 1970-01-01
  • 2017-04-14
  • 2012-09-26
  • 2011-05-07
  • 1970-01-01
  • 2013-07-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多