Apollo 客户端查询报错:“Network error: Failed to fetch”如何排查?
Posted
技术标签:
【中文标题】Apollo 客户端查询报错:“Network error: Failed to fetch”如何排查?【英文标题】:Apollo client query error: "Network error: Failed to fetch" How to troubleshoot? 【发布时间】:2018-08-29 21:17:50 【问题描述】:Apollo 服务器已设置,并且在使用 graphiql 时正确响应查询。
具有服务器端渲染的现有 react-redux 应用程序需要开始使用 graphql 并进行此查询。
此应用程序的一个组件已设置为执行相同的查询,它似乎正在执行网络请求,但它失败了
Error: "graphQLErrors":[],"networkError":,"message":"Network error: Failed to fetch"
任何故障排除建议?
【问题讨论】:
Network error
的常见问题是DNS解析失败,连接因无响应而关闭。
【参考方案1】:
我在 localhost 上运行 apollo 客户端,在 someDomain.com 上运行 apollo 服务器,所以这是一个 CORS 问题。加载在chrome隐身模式下进行查询的页面并刷新后,在chrome开发工具控制台中发现了这个错误:
httpLink.js:71 OPTIONS https://someDomain.com/graphql 405 (Method Not Allowed)
(anonymous) @ httpLink.js:71
...
(index):1 Failed to load https://someDomain.com/graphql: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://localhost:8443' is therefore not allowed access. The response had HTTP status code 405. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
此(仅限测试)设置的快速解决方法是在 express apollo 服务器上设置 cors,就像这篇文章所建议的那样。 https://blog.graph.cool/enabling-cors-for-express-graphql-apollo-server-1ef999bfb38d
【讨论】:
【参考方案2】:这确实是 cors 问题。我试图通过使用 express 来修复它。但它不适用于 Apollo GraphQL。
const corsOptions =
origin: "http://localhost:3000",
credentials: true
;
app.use(cors(corsOptions));
所以,我尝试在 GraphQL 服务器中配置 cors 并且成功了。
对于 Apollo 服务器
const corsOptions =
origin: "http://localhost:3000",
credentials: true
;
const server = new ApolloServer(
typeDefs,
resolvers,
cors: corsOptions
);
server.listen().then(( url ) =>
console.log(`? Server ready at $url`);
);
对于 GraphQL 瑜伽
const options =
cors: corsOptions
;
server.start(options, () =>
console.log("Server is running on http://localhost:4000")
);
【讨论】:
【参考方案3】:如果您通过 Apollo 在请求中传递 null
HEADER 也可能出现此错误,例如:
const middlewareLink = setContext(() => (
headers:
'authorization': `Bearer $FeedierExchanger.token` || null
));
改成:
const middlewareLink = setContext(() => (
headers:
'authorization': `Bearer $FeedierExchanger.token` || ''
));
或者去掉这部分:
|| ''
如果您有正确的后端验证。
【讨论】:
【参考方案4】:您需要做的就是为您的 Apollo-Graphql 服务器启用 cors 库
yarn add cors / npm install cors
现在找到你的 app.js 或 server.js(基本上是你的服务器的入口文件)
添加下面几行
const cors = require('cors');
app.use(cors()); // 确保你在这之前已经初始化了 express。
【讨论】:
【参考方案5】:尝试在代码顶部使用 cors 中间件。这会在创建 graphql 端点之前首先初始化跨域资源共享。
enter const urlencoded = require("express");
const express = require("express");
const app = express(); //create an express application
const helmet = require("helmet"); //require helment from node modules
const cors = require("cors"); //cross-origin-resource sharing
const mR = require("./routes/main");
const schema = require("./graph-schema/schema");
const mongoose = require("mongoose");
//cross-origin-resources-sharing defined at the top before your graphql endpoint
app.use(
cors(
optionsSuccessStatus: 200, //option sucess status
origin: "http://localhost:3000", //origin allowed to access the server
)
);
//connect to database
mongoose.connect("mongodb://localhost:27017/Graphql_tutorial",
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
);
//graphql area
const graphqlHTTP = require("express-graphql"); //This allows express to understand graphql and lunch its api.
app.use(
"/graphql",
graphqlHTTP(
schema,
graphiql: true,
)
);//code here
【讨论】:
以上是关于Apollo 客户端查询报错:“Network error: Failed to fetch”如何排查?的主要内容,如果未能解决你的问题,请参考以下文章
在查询组件之外显示 Apollo 客户端查询加载的最佳实践?