node.js - CORS 预检响应与实际响应不匹配

标签 node.js express cors apollo apollo-server

在我的 node.js 服务器中,我包含了 CORS 作为中间件,如下所示:

app.use(cors({ origin: 'http://<CORRECT_ORIGIN_URL>:3030', credentials: true }))

我在发送请求的应用程序中使用 Apollo Client,并在初始化 ApolloClient 时将凭据设置为“include”,如下所示:

// Create a WebSocket link
const wsLink = process.browser ? new WebSocketLink({
    uri: `ws://<CORRECT_REQUEST_URL>:8000/graphql`,
    options: {
        reconnect: true,
    },
}) : null

// Create an http link (use batch, allow cookies response from server)
const httpLink = new BatchHttpLink({
    uri: 'http://<CORRECT_REQUEST_URL>/api/',
    credentials: 'include'
})


// Split terminating link for websocket and http requests
const terminatingLink = process.browser ? split(
    ({ query }) => {
        const { kind, operation } = getMainDefinition(query)
        return kind === 'OperationDefinition' && operation === 'subscription'
    },
    wsLink,
    httpLink,
) : httpLink

// Create Apollo client
const client = new ApolloClient({
    link: ApolloLink.from([authLink, errorLink, terminatingLink])
})

当我尝试登录时,我可以看到发送了预检 OPTIONS 请求并获得了正确的响应:

请求 header (OPTIONS 请求)

Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST
Origin: http://<CORRECT_ORIGIN_URL>:3030
Referer: http://<CORRECT_ORIGIN_URL>/login

响应 header (OPTIONS 请求)

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Access-Control-Allow-Origin: http://<CORRECT_ORIGIN_URL>:3030
Connection: keep-alive
Content-Length: 0
Date: Wed, 20 Mar 2019 03:09:14 GMT
Server: nginx/1.15.5 (Ubuntu)
Vary: Origin, Access-Control-Request-Headers
X-Powered-By: Express

然而,当发送实际的 POST 请求时,我得到以下响应:

响应 header (POST 请求)

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json
Date: Wed, 20 Mar 2019 03:09:15 GMT
Server: nginx/1.15.5 (Ubuntu)
Transfer-Encoding: chunked
Vary: Accept-Encoding, Origin
X-Powered-By: Express

I have no idea why the response headers are different in the post request when the options preflight show that it should be correct.

这种不正确的 POST 响应会导致客户端出现以下错误消息:

Access to fetch at 'http://<CORRECT_REQUEST_URL/api/' from origin
'http://<CORRECT_ORIGIN_URL>:3030' 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'.

我已经尝试使用谷歌搜索和搜索 stackoverflow 来寻找解决方案,但找不到任何东西。有什么想法吗?

最佳答案

我解决了我的问题。

问题是 Apollo Server 默认添加了 CORS 中间件,这覆盖了我的 CORS 设置。来自 Apollo's documentation :

Provide false to remove CORS middleware entirely, or true to use your middleware's default configuration.

The default value is true.

为了解决这个问题,我只需要在 Apollo 中禁用 CORS 功能,这只需要在 .applyMiddleware 中设置 cors: false像这样:

server.applyMiddleware({
    app,
    path: '/',
    cors: false,
});

进一步引用:

关于node.js - CORS 预检响应与实际响应不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55253237/

相关文章:

javascript - 对于 HTTP OPTIONS 请求,拥有响应正文有什么意义吗?

javascript - 为什么将方法放在类的原型(prototype)上而不是在构造函数中声明它们?

javascript - 大流量生产环境集群Node JS

javascript - Passportjs 阻止注册后自动登录

node.js - 如何在 Windows 10 上安装 bcrypt

javascript - 最好的写法是什么? Node JS

javascript - 如何在连接到 API 的我的移动应用程序 (cordova) 上启用跨源资源共享(在 Yii 中)

node.js - 如何通过 https 请求从 Node 调用 Azure 客户端?

javascript - 将变量从 JavaScript 传递到 Node.js

javascript - 尝试使用 api/oEmbed 从 Vimeo 上的剪辑获取数据时出现 CORS 问题