Javascript 为什么在使用cors进行服务器端apollo客户端查询时会出现500 http错误?
我正在使用Next.js+react apollo+apollo server+express作为我的网站。最近,我添加了cookie身份验证,因此必须在服务器中启用CORS才能使cookie身份验证工作。然而,我看到apollo客户端查询在服务器端执行时会导致http 500状态。在客户端执行相同的查询时,将成功解析。我很困惑,因为我实际上预计问题会发生在客户端,因为CORS在客户端的影响更大。我不确定是什么原因导致了这个问题,任何建议都是非常欢迎的 错误本身如下所示: 阿波罗错误:网络错误:请求到 失败,原因:写入EPROTO 140152723232576:错误:14094410:SSL 例程:ssl3\u读取字节:sslv3警报握手 失败:../deps/openssl/openssl/ssl/record/rec_layer_s3.c:1544:ssl 40号警报 我有一个用于页面查询的HOC:Javascript 为什么在使用cors进行服务器端apollo客户端查询时会出现500 http错误?,javascript,ssl,next.js,apollo-client,Javascript,Ssl,Next.js,Apollo Client,我正在使用Next.js+react apollo+apollo server+express作为我的网站。最近,我添加了cookie身份验证,因此必须在服务器中启用CORS才能使cookie身份验证工作。然而,我看到apollo客户端查询在服务器端执行时会导致http 500状态。在客户端执行相同的查询时,将成功解析。我很困惑,因为我实际上预计问题会发生在客户端,因为CORS在客户端的影响更大。我不确定是什么原因导致了这个问题,任何建议都是非常欢迎的 错误本身如下所示: 阿波罗错误:网络错误:
const withQuery = (Page, query, variables, errorPolicy = 'none') => {
Page.getInitialProps = async ctx => {
const { apolloClient } = ctx;
try {
const { data } = await apolloClient.query({
query,
variables: vars,
errorPolicy
});
return { data };
} catch (error) {
return { errorStatusCode: error.networkError ? '500' : '404' };
}
};
// if (typeof window === 'undefined') { // THIS CODE IS CAUSING THE ISSUE
// return Page;
// }
}
以下是我启动apollo客户端的方式:
import withApollo from 'next-with-apollo';
import ApolloClient, { InMemoryCache } from 'apollo-boost';
import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import introspectionQueryResultData from '../../fragmentTypes.json';
const fragmentMatcher = new IntrospectionFragmentMatcher({
introspectionQueryResultData
});
function createClient({ ctx, headers, initialState }) {
return new ApolloClient({
credentials: 'include',
uri: 'some_graphql_url',
cache: new InMemoryCache({ fragmentMatcher }).restore(initialState || {}),
headers
});
}
export default withApollo(createClient, { getDataFromTree: 'ssr' });
这是我的服务器代码:
从“cors”导入cors
const express=require('express')
const{ApolloServer}=require('apollo-server-express')
const{schema}=require('./模型')
const server=新服务器({
模式,
})
//接受Cookie所需的设置
常数常数={
原点:函数(原点,回调){
if(corsWhitelist.indexOf(origin)!==-1 | |!origin){
回调(null,true)
}否则{
回调(新错误(`${origin}-CORS`不允许)
}
},
凭据:正确
}
让app=express()
应用程序使用(cors(corsOptions))
applyMiddleware({app,cors:false})
const serverUrl=`my_server_url`
app.listen({port},()=>console.log(`您的代码不完整
const express=require('express');
const{ApolloServer,gql}=require('apollo-server-express');
//使用GraphQL模式语言构建模式
常量typeDefs=gql`
类型查询{
你好:字符串
}
`;
//为架构字段提供解析器函数
常量解析程序={
查询:{
你好:()=>“你好,世界!”,
},
};
const server=new ApolloServer({typeDefs,resolvers});
常量app=express();
applyMiddleware({app});
app.listen({port:4000},()=>
console.log(`我出现错误的原因是我将所有的头从serverside(express.js)传递给Amazon Cloudfront,包括host
头。因为我的网站配置为使用它,所以传递正确的服务器名很重要(此参数用于确定从IP地址为哪个虚拟主机提供服务的SSL证书)。Apollo客户端使用node fetch
npm包进行http请求,而npm包又使用https
node.js模块。如果host
头存在,则https
将服务器名设置为host
的值,否则服务器名获取主机名的值(mywebsite.com)因此,在我的例子中,服务器名是bla.bla.elasticbeanstalk.com
,这当然会导致SSL握手错误,因为SSL证书是针对mywebsite.com的。我写了更多信息。我所知道的开始解决500内部服务器错误的唯一方法是查看服务器端日志文件。这个答案是正确的吗你的问题?@EternalHour没有。我在网站上从来没有出现过SSL问题,所以它们只是在我添加CORS时才开始出现的。问题中引用的错误消息似乎非常清楚地表明了SSL错误中存在的实际问题。我想这里的任何人都猜不出你为什么会在之后开始出现SSL问题您“添加了CORS”,但这仍然是一个SSL问题,而不是CORS问题。我正在导入包含typeDefs和解析器的文件中的schema
对象。从vercel构建时,我收到了相同的错误(使用getStaticProps获取数据,即SSG)。您知道此修复程序如何应用于那里吗?问题发生在我的代码中,因为我在初始化ApolloClient
时覆盖了headers
对象。它与构建无关。您应该检查您的头,也许可以阅读我编写的链接,其中解释了更多有关SNI错误的信息。我确实看了一下,但认为我无法通过getStaticProps中的标题发送到我的客户端。由于getStaticProps在生成时运行,因此它不会在生成静态HTML时接收仅在请求时可用的数据,例如查询参数或HTTP标题。()
const withQuery = (Page, query, variables, errorPolicy = 'none') => {
Page.getInitialProps = async ctx => {
const { apolloClient } = ctx;
try {
const { data } = await apolloClient.query({
query,
variables: vars,
errorPolicy
});
return { data };
} catch (error) {
return { errorStatusCode: error.networkError ? '500' : '404' };
}
};
// if (typeof window === 'undefined') { // THIS CODE IS CAUSING THE ISSUE
// return Page;
// }
}
import withApollo from 'next-with-apollo';
import ApolloClient, { InMemoryCache } from 'apollo-boost';
import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import introspectionQueryResultData from '../../fragmentTypes.json';
const fragmentMatcher = new IntrospectionFragmentMatcher({
introspectionQueryResultData
});
function createClient({ ctx, headers, initialState }) {
return new ApolloClient({
credentials: 'include',
uri: 'some_graphql_url',
cache: new InMemoryCache({ fragmentMatcher }).restore(initialState || {}),
headers
});
}
export default withApollo(createClient, { getDataFromTree: 'ssr' });