【问题标题】:GraphQL requests from React frontend aren't making it to the server来自 React 前端的 GraphQL 请求没有发送到服务器
【发布时间】:2022-10-12 23:10:54
【问题描述】:

我正在开发一个使用 React 作为客户端和 Apollo Express 作为服务器的应用程序,由于某种原因,GraphQL 请求没有发送到服务器。我有一个注册表单;当我输入信息并按提交时,所有数据都被正确收集,但由于某种原因,当我调用 useMutation 返回的函数时,它返回 null。在浏览器控制台中,我收到以下错误:Response not successful: Received status code 404

通过将 console.logs 放入相关的解析器中,我发现当我按下提交时它没有运行。但是,如果我转到 localhost:3001/graphql 端点,我能够成功执行突变;解析器自己工作。我有另一个带有 React 前端和 Apollo Express 后端的工作应用程序,但是从那里引用甚至复制代码都没有帮助。

这是我能想象到的每个代码块都是相关的:

client/src/App.js:

import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import {ApolloProvider, ApolloClient, InMemoryCache, createHttpLink} from '@apollo/client';
import {setContext} from '@apollo/client/link/context';

import Splash from './components/Splash';
import Dashboard from './components/Dashboard.js';
// import Resources from './components/Resources.js';

// hook up the client to the graphql endpoint
const httpLink = createHttpLink({
    uri: '/graphql'
});

// attach authorization property to every request
const authLink = setContext((_, {headers}) => {
    const token = localStorage.getItem('id_token');

    return {
        headers: {
            ...headers,
            Authorization: token ? `Bearer ${token}` : ''
        }
    };
});

// instantiate apollo w/ cache
const client = new ApolloClient({
    link: authLink.concat(httpLink),
    cache: new InMemoryCache()
});

function App() {
  return (
    <ApolloProvider client={client}>
      <Router>
        <Splash />
        <Routes>
          <Route path="/" element={<Splash />} />
          <Route path="/dashboard" element={<Dashboard />} />
          {/*<Route exact path="/resources" element={Resources} />*/}
          <Route render={() => <h1 className="display-2">Wrong page!</h1>} />
        </Routes>
      </Router>
    </ApolloProvider>
  );
}

export default App;

client/src/components/SignupModal.js:

import React, { useState } from 'react';
import Auth from '../utils/auth';
import { useMutation } from '@apollo/client';
import { ADD_USER } from '../utils/mutations';
import { Navigate } from 'react-router-dom';
import './LoginModal.css';

function SignUp() {
  const [formState, setFormState] = useState({
    username: '',
    password: '',
    email: '',
  });
  const { username, password, email } = formState;

  const [addUser, { error }] = useMutation(ADD_USER);

  function handleChange(e) {
    setFormState({ ...formState, [e.target.name]: e.target.value });
  }

  const handleSubmit = async (e) => {
    e.preventDefault();

    console.log('ERROR', error);
    try {
      const mutationResponse = await addUser({
        variables: {
          username: formState.username,
          email: formState.email,
          password: formState.password,
        },
      });
      // any console.logs after this point don't run

      const token = mutationResponse.data.addUser.token;
      Auth.login(token);

      <Navigate to="/dashboard" replace={true} />;
    } catch (err) {
      console.error(err);
    }
  };

  return (
    [...]
  );
}

export default SignUp;

client/src/utils/mutations.js:

import {gql} from '@apollo/client';

export const ADD_USER = gql`
mutation addUser($username: String!, $email: String!, $password: String!) {
    addUser(username: $username, email: $email, password: $password) {
        token
        user {
            _id
            username
            email
        }
    }
}
`;

server/server.js:

const express = require('express');
const {ApolloServer} = require('apollo-server-express');
const path = require('path');

const {typeDefs, resolvers} = require('./schemas');
const {authMiddleware} = require('./utils/auth');
const db = require('./config/connection');

const PORT = process.env.PORT || 3001;

const server = new ApolloServer({
    typeDefs,
    resolvers,
    context: authMiddleware
});
const app = express();

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

const startApolloServer = async (typeDefs, resolvers) => {
    await server.start();
    server.applyMiddleware({app});
}

// if we're in production, serve client/build as static assets
if (process.env.NODE_ENV === 'production') {
  app.use(express.static(path.join(__dirname, '../client/build')));
};

app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, '../client/build/index.html'));
});

db.once('open', () => {
    app.listen(PORT, () => {
        console.log(`API server running on port ${PORT}!`);
        console.log(
            `Use GraphQL at http://localhost:${PORT}${server.graphqlPath}`
        );
    });
});

startApolloServer(typeDefs, resolvers);

server/schemas/resolvers.js:

const { User } = require('../models');
const { signToken } = require('../utils/auth');

const resolvers = {
  Query: {
    [...]
  },
  Mutation: {
    addUser: async (_, args) => {
      // console.logs here run if i run this mutation in apollo studio, but not if i try to call it from the frontend
      const user = await User.create(args);
      const token = signToken(user);
      return { token, user };
    }
  }
};

module.exports = resolvers;

【问题讨论】:

  • 你知道 404 是什么意思,所以你应该可以自己调试。如果您能够在一个端点上进行 GraphQL 查询,请使用 Chrome 开发人员工具来验证在网络选项卡中将哪个 URL 发布到。然后将其与错误页面所击中的端点进行比较。
  • @AndyRay 请求将发送到 localhost:3000/graphql。我不知道如何改变这一点。

标签: reactjs graphql apollo apollo-client


【解决方案1】:

解决了。我忘记在客户端的 package.json 中添加代理值 - "proxy": "http://localhost:3001"。那解决了它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-19
    • 2020-05-07
    • 2019-12-24
    • 2020-08-13
    • 2018-06-26
    • 1970-01-01
    • 2023-01-27
    • 2020-03-14
    相关资源
    最近更新 更多