Express CORs 策略阻止 Apollo 客户端从服务器获取

Posted

技术标签:

【中文标题】Express CORs 策略阻止 Apollo 客户端从服务器获取【英文标题】:Express CORs policy preventing Apollo client from fetching from server 【发布时间】:2020-01-30 09:52:46 【问题描述】:

我在http://localhost:3000 上运行一个反应开发服务器,在http://localhost:8080 上运行一个快速服务器,并且正在使用 Apollo 客户端来查询服务器。为了使会话数据能够从客户端传递到服务器,我在初始化 Apollo 客户端时添加了credentials: "include" 参数。

我在我的 express 服务器中添加了以下行(在定义路由之前)来配置 cors:

app.use(cors( credentials: true, origin: "http://localhost:3000" ));

但是,在执行查询时,会抛出以下错误:

Access to fetch at 'http://localhost:8080/graphql' from origin 'http://localhost:3000' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

为什么标题响应显示为*?是我错误地配置了 COR 还是遗漏了其他内容?

【问题讨论】:

【参考方案1】:

既然您有 credentials: true,您应该在 fetch 调用中包含凭据:

fetch(url, 
  credentials: 'include'  
)

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true); 
xhr.withCredentials = true; 
xhr.send(null);

这将发送标头设置为Access-Control-Allow-Credentials: true的请求

没有这个,它会被拒绝。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials

【讨论】:

我相信我已经拥有与 apollographql.com/docs/react/networking/authentication 类似的 Apollo 了 您是否尝试将凭据设置为 false 以排除这是后端的配置问题?【参考方案2】:

此错误是浏览器生成的 CORS 错误。在前端使用 npm install --save http-proxy-middleware 并在 frontend/src/setupProxy.js 中添加 setupProxy.js 文件

setupProxy.js

//run defferent ports for website and api server 
const proxy = require('http-proxy-middleware');

module.exports = function(app) 
  app.use(proxy('/api/',  target: 'http://localhost:8080/' )); //make change as per your application (So you can access your data on  http://localhost:8080/api/ )
;

替代解决方案

如果您使用的是 webpack 开发服务器,这是另一种代理请求的方法,而无需对 NodeJS 进行更改。将此添加到 package.json:

  "proxy": "http://localhost:8080"

应该允许 webpack 将发往 http://localhost:3000 的请求代理到 http://localhost:8080

但这意味着需要向http://localhost:3000而不是http://localhost:8080提出请求。

【讨论】:

这将允许所有客户端访问 API,并且设置原点的整个点将被取消 这只是为了在本地机器上使用具有不同 oring 的同一主机运行您的应用程序。当您将代码投入生产时,它不会影响您的代码。 在这种情况下,它会起作用。我已经编辑了您的答案,以包含使用 create-react-app 的情况的替代解决方案。 充其量,这是一个针对开发的创可贴解决方案。这里的假设是,在生产中,客户端 Web 应用程序和 API 将在同一个域中可用。在这种情况下,您不再需要处理跨域请求,也不再需要 CORS。然而,实际上,API 的域很可能实际上会有所不同,即使在生产环境中也是如此,并且需要正确配置 CORS。【参考方案3】:

我在这里遇到的问题是,尽管为 express 启用了 CORS:

app.use(cors( credentials: true, origin: "http://localhost:3000" ));

GraphQL 中间件覆盖了设置。如果使用 Apollo 服务器和相关的中间件,请确保传递 cors: false 参数,如下所示。

gqlServer.applyMiddleware( app, path: "/graphql", cors: false );

【讨论】:

非常感谢,这对我有用。问题虽然;我怎样才能确定这个解决方案没有完全禁用 cors? 尝试从不同的主机运行您的客户端。核心策略应该阻止请求 会的,谢谢。为您的解决方案 +1,因为它似乎对我有用。 感谢这个人!我一直遇到这个奇怪的错误,我只需要关闭graphql上的cors。非常感谢!

以上是关于Express CORs 策略阻止 Apollo 客户端从服务器获取的主要内容,如果未能解决你的问题,请参考以下文章

CORS 策略阻止请求,即使访问允许来源设置为 *

被部署在 Firebase Functions 上的快速服务器的 CORS 策略阻止,即使定义了 cors

在运行本地 API 实例的 Angular 应用程序中解决“被 CORS 策略阻止”错误

Apollo Express CORS 选项

cors错误:没有'Access-Control-Allow-Origin'标头apollo-server-express

Safari 阻止对 Express API 的 CORS 请求