为啥我总是得到一个不允许通配符 * 的 cors 错误,尽管我在服务器上指定了一个来源?
Posted
技术标签:
【中文标题】为啥我总是得到一个不允许通配符 * 的 cors 错误,尽管我在服务器上指定了一个来源?【英文标题】:Why do I always get a cors error that wildcard * is not allowed, although I specified a origin on the server?为什么我总是得到一个不允许通配符 * 的 cors 错误,尽管我在服务器上指定了一个来源? 【发布时间】:2019-11-19 02:22:45 【问题描述】:我使用 Apollo Server 和 Apollo Client 创建了一个简单的 graphQL 聊天。
它还使用会话 cookie,所以我使用 npm 包 cors
初始化服务器,如下所示:
app.use(
cors(
credentials: true,
origin: "http://localhost:3000"
)
);
在客户端,我使用 apollo 客户端并像这样创建一个 http 链接:
const httpLink = new HttpLink(
uri: "http://localhost:4000/graphql",
credentials: "include"
);
所以我包含凭据并且服务器具有我的客户端的来源(确实是 http://localhost:3000 - create-react-app 默认值)。
当我想运行查询时,我在浏览器控制台中收到此错误:
从源“http://localhost:3000”获取“http://localhost:4000/graphql”的访问权限已被 CORS 策略阻止:响应中的“Access-Control-Allow-Origin”标头的值不能是通配符“* ' 当请求的凭据模式为 'include' 时。
为什么它说响应头设置了通配符 *,但在 cors 上我设置了特定的来源,所以它不应该是通配符对吗?
我在这里错过了什么?当然,我也重新启动了两台服务器。
当我这样设置客户端时:
const httpLink = new HttpLink(
uri: "http://localhost:4000/graphql",
credentials: "same-origin"
);
我没有收到来自 cors 的错误消息,但我没有收到来自服务器的 cookie。 Cookie 之所以有效,是因为在 graphQL Playground 上一切正常。
如需查看完整代码:https://github.com/SelfDevTV/graphql-simple-chat
【问题讨论】:
【参考方案1】:问题解决了。
在我来自服务器的index.js
文件中。
下面几行我将 express 应用程序作为中间件应用到 apollo 服务器实例,如下所示:
server.applyMiddleware( app );
但这会覆盖我在上面设置的 cors 选项。
所以我必须这样称呼它:server.applyMiddleware( app, cors: false );
现在一切正常:)
【讨论】:
这只是关闭 cors。更好的解决方案是在您的 package.json"proxy": "http://localhost:4000/",
中为本地开发设置一个代理,它告诉您通过您的应用程序对代理端口 4000 做出反应以进行开发。对于生产,您需要将服务器和前端捆绑在一起
真的关掉了吗?因为这意味着凭据不会传递给客户端?所以cookies不会起作用,但他们会这样做吗?我是从 create-react-app 文件夹还是服务器的 package.json 设置你在 package.json 中提到的这个代理?
是的,cors: false
正在关闭 cors,这与凭据或 cookie 无关。这是一种安全保护,在这里可以更好地解释:medium.com/@baphemot/understanding-cors-18ad6b478e2b 至于代理,你把它放在你的 react package.json 中。
好的,当我设置这个代理时。接下来我到底要做什么。像这样使用 cors 包启用 cors:app.use( cors( credentials: true, origin: ["http://localhost:3000"] ) );
并且还在 apollo 服务器实例上设置 cors:true
?在客户端我可以设置credentials: "same-origin"
?像这样正确吗? 编辑: 不能以这种方式工作。 same-origin
有效,但没有 cookie。 include
与通配符相同的 cors 错误。
你不应该在任何一方显式地做任何事情,只需在反应端设置代理,它就会点击http://localhost:4000
,就像它点击http://localhost:3000
一样。以下是官方文档:facebook.github.io/create-react-app/docs/…【参考方案2】:
您可以改为告诉 Apollo 服务器如何配置 cors。
const corsOptions =
origin: "http://localhost:3000",
credentials: true
server.applyMiddleware(
app,
cors: corsOptions
)
那么你就可以完全消除 express cors 中间件了。
【讨论】:
这对我有用。我认为这应该是公认的答案。 当我使用http://localhost:3000
或true
作为我的来源时,它起作用了,但当我在网址末尾添加*
、/
或/*
时,它就不行了,例如http://localhost:3000/
。我还在我的env.dev
文件中添加了这个作为变量:CLIENT_URL=http://localhost:3000
,然后通过origin: process.env.CLIENT_URL
将它加载到服务器索引中,效果很好以上是关于为啥我总是得到一个不允许通配符 * 的 cors 错误,尽管我在服务器上指定了一个来源?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我在使用 location.href 时总是被 CORS 阻止