node.js - 如何修复错误:only absolute URLS are supported in react ssr graphql

标签 node.js reactjs redux apollo server-side-rendering

我正在使用 apollo 设置服务器端渲染,以便在服务器端设置 graphql,但是当我尝试在 cli 中出现的一个组件中使用查询时,我现在不知道如何遇到这个问题:

(node:4440) UnhandledPromiseRejectionWarning: Error: Network error: Only absolute URLs are supported
at new ApolloError (G:\Project\node_modules\apollo-client\bundle.umd.js:59:32)
    at QueryManager.<anonymous> (G:\Project\node_modules\apollo-client\bundle.umd.js:13:49)

如果您现在发生了什么,请告诉我。

服务器代码

import React  from 'react'
import routes from '../../client/Routes'

import {StaticRouter} from 'react-router-dom'
import {Provider} from 'react-redux'
import {renderRoutes} from 'react-router-config'
import {AES} from 'crypto-js';
import {Helmet} from "react-helmet";
import serialize from 'serialize-javascript' ;

import  ApolloClient from 'apollo-client';
import { ApolloProvider, renderToStringWithData  } from 'react-apollo';
import { InMemoryCache } from "apollo-cache-inmemory";
import { ApolloLink } from 'apollo-link';
import { errorLink , queryOrMutationLink , getCircularReplacer } from './links';

import fetch from 'node-fetch';

export default async(req,store,context)=>{
    const links = [errorLink,queryOrMutationLink({
        fetch,
        uri: 'http:localhost:3000/api/graphql',
    })]
    const client = new ApolloClient({
        ssrMode: true,
        link:ApolloLink.from(links),
        cache: new InMemoryCache()
    });
    const component = (
        <ApolloProvider client={client}>
            <Provider store={store}>
                <StaticRouter location={req.path} context={context}>
                    {renderRoutes(routes)}
                </StaticRouter>
            </Provider>
        </ApolloProvider>
    )
    return renderToStringWithData(component).then(content=>{
        let serializedStore = serialize(store.getState())
        let hashedUsersList = AES.encrypt(serializedStore, 'secret key 123');
        const helmet        = Helmet.renderStatic();
        return `
            <html>
                <head>
                    ${helmet.title.toString()}
                    ${helmet.meta.toString()}
                    ${helmet.link.toString()}
                    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/css/materialize.min.css">
                    <link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
                    <script>window.INITIAL_STATE = ${JSON.stringify(hashedUsersList, getCircularReplacer())}</script>
                </head>
                <body>
                    <div id="root">${content}</div>
                    <script src="/public-bundle.js"></script>
                    <script>window.__APOLLO_STATE__=${JSON.stringify(client.extract(),getCircularReplacer())}</script>
                </body>
            </html>`
    })
}

import React from 'react';
import {hydrate}from 'react-dom';

//-----------Redux
import {Provider} from 'react-redux';
import {createStore, applyMiddleware,compose} from 'redux';
import thunk from 'redux-thunk';
import {AES,enc,} from 'crypto-js'
import axios from 'axios'
//-----------Router
import {BrowserRouter} from 'react-router-dom';
import routes from './Routes';
import {renderRoutes} from 'react-router-config'

//-----------Internal_import
import reducers from './store/reducers';

//-----------GraphQL[APOLLO_CLIENT]
import ApolloClient       from 'apollo-client';
import { InMemoryCache }  from 'apollo-cache-inmemory';
import { createHttpLink } from 'apollo-link-http';
import { ApolloProvider } from 'react-apollo';
import {fetch} from 'node-fetch';

const client = new ApolloClient({
    connectToDevTools: true,
    link: createHttpLink({
        uri: 'http:localhost:3000/api/graphql',
        credentials:'same-origin'
    }),
    cache: new InMemoryCache({dataIdFromObject:o=>o.id}).restore(window.__APOLLO_STATE__),
})

const axiosInstance = axios.create({baseURL: '/api'});
const composeEnhancers = typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(applyMiddleware(thunk.withExtraArgument(axiosInstance)));

let DecryptUsersList  = AES.decrypt(window.INITIAL_STATE, 'secret key 123');
let UsersList_State = JSON.parse(DecryptUsersList.toString(enc.Utf8))

const store = createStore(reducers,UsersList_State,enhancer)

hydrate(
    <ApolloProvider client={client}>
        <Provider store={store}>
            <BrowserRouter>
                {renderRoutes(routes)}
            </BrowserRouter>
        </Provider>
    </ApolloProvider>
    ,document.querySelector('#root')
)

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import {connect} from 'react-redux';
import {graphql} from 'react-apollo';
import gql from 'graphql-tag';
const Header = (props)=>{
  console.log(props)
  const renderButtons=()=>{
    if (props.user) {
      return (
        <div>
          <li><Link to="/admins">Admins</Link></li>
          <li><a href="/api/logout">Logout</a></li>
        </div>
      );
    } else {
      return (
        <div>
          <li>
            <Link to="/users">Users</Link>
          </li>
          <li>
            <Link to="/admins">Admins</Link>
          </li>
          <li>
            <Link to="/Signin">SignIn</Link>
          </li>
          <li>
            <Link to="/Signup">SignUp</Link>
          </li>
          <li>
            <a href="/api/auth/google">Login via google</a>
          </li>
        </div>
      );
    }
  }
    return (
      <nav>
        <div className="nav-wrapper">
          <Link to="/" className="brand-logo left">
            Home
          </Link>
          <ul className="right">
            {renderButtons()}
          </ul>
        </div>
      </nav>
    );
}

const query = gql`
{
    user{
      id
      email
      name
    }
}
`
const mapStateToProps =({auth})=>({user:auth.user})
export default connect(mapStateToProps,null)(graphql(query)(Header));

最佳答案

您的网址似乎有拼写错误 而不是:

uri: 'http:localhost:3000/api/graphql',

您需要使用:

uri:'http://localhost:3000/api/graphql',

使用 apollo 绝对 url 意味着 api url 必须以 http://https://

开头

关于node.js - 如何修复错误:only absolute URLS are supported in react ssr graphql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55312868/

相关文章:

javascript - Nodejs 事件循环——与顶层代码的交互

reactjs - 使用多个数据集重新绘制 ComposedChart?

javascript - 创建 React 应用程序后,在 cmd 上 npm start 总是给出错误

node.js - 这是 Node.js 和 Socket.io 的良好身份验证方案吗?

javascript - 如何在 Redux/React 应用程序中加载数据 "on-demand"

node.js - 使用 NodeJS 和 AWS S3 将损坏/截断的 mp4 上传到 S3 存储桶

javascript - 所有 Node "callback"函数都可能是异步的吗?

node.js - 函数返回未定义、预期的 Promise 或值 Firebase 日志错误

reactjs - 当上下文消费者中的任何状态发生变化时,React 是否会重新渲染所有组件?

reactjs - 使用 dispatch 和 getState 时的 Redux 操作返回类型