Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 下一个js和Apollo-Cookie未被传递_Javascript_Reactjs_Graphql_Apollo_Next.js - Fatal编程技术网

Javascript 下一个js和Apollo-Cookie未被传递

Javascript 下一个js和Apollo-Cookie未被传递,javascript,reactjs,graphql,apollo,next.js,Javascript,Reactjs,Graphql,Apollo,Next.js,我正在Apollo上使用Next JS,并在我的with data HOC中使用以下配置进行了设置: import { ApolloClient } from 'apollo-client'; import { InMemoryCache } from 'apollo-cache-inmemory'; import { HttpLink } from 'apollo-link-http'; import { onError } from 'apollo-link-error'; import {

我正在Apollo上使用Next JS,并在我的with data HOC中使用以下配置进行了设置:

import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';
import { onError } from 'apollo-link-error';
import { withClientState } from 'apollo-link-state';
import { getMainDefinition } from 'apollo-utilities';
import { ApolloLink, Observable, split  } from 'apollo-link';
import { WebSocketLink } from 'apollo-link-ws';
import withApollo from 'next-with-apollo';
import { SubscriptionClient } from 'subscriptions-transport-ws';

import { endpoint, prodEndpoint, WSendpoint, WSprodEndpoint } from '../config';

import defaults from '../apollo-state/graphql/default-state';
import Mutation from '../apollo-state/resolvers/mutation-resolvers';

const wsClient = process.browser ? new SubscriptionClient(process.env.NODE_ENV === 'development' ? WSendpoint : WSprodEndpoint, {
  reconnect: true,
}) : null;


function createClient({ headers }) {
  const wsLink = process.browser ? new WebSocketLink(wsClient) : null;
  const httpLink = new HttpLink({
    uri: process.env.NODE_ENV === 'development' ? endpoint : prodEndpoint,
    credentials: 'include',
  })

  const link = process.browser ? split(
    // split based on operation type
    ({ query }) => {
      const { kind, operation } = getMainDefinition(query);
      return kind === 'OperationDefinition' && operation === 'subscription';
    },
    wsLink,
    httpLink,
  ) : httpLink;

  const cache = new InMemoryCache();

  const request = async operation => {
    const contextObj = {
      fetchOptions: {
        credentials: 'include'
      },
      headers
    };
    operation.setContext(contextObj);
  }; 

  const requestLink = new ApolloLink((operation, forward) =>
    new Observable(observer => {
      let handle;
      Promise.resolve(operation)
        .then(oper => request(oper))
        .then(() => {
          handle = forward(operation).subscribe({
            next: observer.next.bind(observer),
            error: observer.error.bind(observer),
            complete: observer.complete.bind(observer),
          });
        })
        .catch(observer.error.bind(observer));

      return () => {
        if (handle) handle.unsubscribe();
      };
    })
  );
  // end custom config functions
  const apolloClient = new ApolloClient({
      credentials: 'include',
      ssrMode: !process.browser,
      link: ApolloLink.from([
        onError(({ graphQLErrors, networkError }) => {
          if (graphQLErrors) {
            console.log(graphQLErrors)
          }
          if (networkError) {
            console.log(networkError)
          }
        }),
        requestLink,
        withClientState({
          defaults, // default state
          resolvers: {
            Mutation // mutations
          },
          cache
        }),
        link
      ]),
      cache
  }); // end new apollo client
  return apolloClient;
}

export { wsClient };
export default withApollo(createClient);
当地一切正常。我可以登录,当我访问站点时,它会自动登录,SSR工作没有问题。但是,当我部署到Next或Heroku时,SSR不起作用

我已经调查了这个问题,似乎这是cookies未随请求一起发送的常见问题:

Apollo配置的这一部分似乎存在问题,其中有时未定义标头,因此未发送cookie:

  const request = async operation => {
    const contextObj = {
      fetchOptions: {
        credentials: 'include'
      },
      headers
    };
    operation.setContext(contextObj);
  }; 
人们提到的一些解决方法是,如果存在cookie头,则手动设置cookie头:

  const request = async operation => {
    const contextObj = {
      fetchOptions: {
        credentials: 'include'
      },
      headers: {
        cookie: headers && headers.cookie
      }
    };
    operation.setContext(contextObj);
  }; 
上面对代码的修改修复了服务器端渲染,但是当我在浏览器中使用登录cookie访问站点时,它将不再自动登录(它使用我的初始方法自动登录,但不会在生产中进行SSR)

有人提到,这可能是因为Now或Heroku在部署应用程序后生成的URL中使用子域,并使用自定义域解决问题。我尝试使用自定义域,但仍遇到问题。我的域设置如下所示:

前端域名:mysite.com 后端域:api.mysite.com

这里有没有人经历过这个问题并能够解决它

如果您发现我的配置或我如何设置域有问题,请告诉我。

很晚了,但请尝试一下 您应该添加cookies选项,如下所示。请确保您的浏览器中有Cookie,即csrftoken。它应该是可用的。希望它能起作用

const request = async operation => { const contextObj = { fetchOptions: { credentials: 'include' }, //################ CHANGE HERE ########## headers: { ...header } cookies: { ...cookies } //###################################### }; operation.setContext(contextObj); }; 常量请求=异步操作=>{ const contextObj={ 获取选项:{ 凭据:“包括” }, //################在这里换车########## 标题:{ …标题 } 曲奇饼:{ …饼干 } //###################################### }; operation.setContext(contextObj); };
这名官员有问题或缺乏能力 这是本报报道的

我将把那些让我能够解决这个问题的评论拼凑在一起

这里是对官方示例的一个修改,由发布,源于发布示例的前一个版本

从“apollo客户端”导入{apollo客户端};
从'apollo cache inmemory'导入{InMemoryCache};
从“阿波罗链接http”导入{HttpLink};
从“同构取消蚀刻”导入提取;
从“../config”导入{endpoint};
导出默认函数createApollopClient(initialState,ctx){
//“ctx”(NextPageContext)将仅出现在服务器上。
//使用它来提取身份验证头(ctx.req)或类似文件。
const enchancedFetch=(url,init)=>
获取(url{
…初始化,
标题:{
…init.headers,
Cookie:ctx.req.headers.Cookie,
},
}).然后(响应=>响应);
返回新客户端({
ssrMode:布尔值(ctx),
链接:新的HttpLink({
uri:endpoint,//服务器URL(必须是绝对的)
凭据:'相同来源',//附加的fetch()选项,如'credentials'或'headers'`
fetch:ctx?enchancedFetch:fetch,
}),
缓存:新建InMemoryCache().restore(初始状态),
});
}
为了让它工作,我还更改了后端的CORS选项


//graphql瑜伽+prisma 1后端(Wes Boss的高级反应课程)
...
const cors=要求(“cors”);
const server=createServer();
var公司={
来源:process.env.FRONTEND_URL,
凭据:正确
};
server.express.use(cors(corsOptions));
...
我还更新了依赖项,直到达到“无纱线警告”状态

"dependencies": {
    "@apollo/react-hooks": "^3.1.5",
    "@apollo/react-ssr": "^3.1.5",
    "@babel/core": "^7.1.2",
    "@types/react": "^16.8.0",
    "apollo-cache-inmemory": "^1.6.6",
    "apollo-client": "^2.6.9",
    "apollo-link-http": "^1.5.17",
    "apollo-utilities": "^1.3.2",
    "graphql": "14.3.1",
    "graphql-tag": "^2.10.3",
    "isomorphic-unfetch": "^3.0.0",
    "next": "latest",
    "prop-types": "^15.6.2",
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  },
  "devDependencies": {
    "babel-plugin-graphql-tag": "^2.5.0"
  }

如果你有任何其他的解决方案,请与我们分享,它真的是注释。如果你没有其他解决方案,@Ngatia Frankline提出的解决方案对我来说真的很有效。我最终在下一个JS服务器上设置了cookie。以下是我为此方法复制的存储库: