CORS预检响应与实际响应不匹配

8
在我的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请求,并返回了正确的响应: 请求头(OPTIONS请求)
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST
Origin: http://<CORRECT_ORIGIN_URL>:3030
Referer: http://<CORRECT_ORIGIN_URL>/login

响应头(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请求被发送时,我得到了以下响应:

响应头信息(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

我不知道为什么在选项预检请求显示响应头应该是正确的时候,POST请求的响应头会不同。

这个不正确的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来解决问题,但是找不到任何有用的信息。你有什么想法吗?
2个回答

7
我解决了我的问题。
问题在于Apollo Server默认添加CORS中间件,这会覆盖我的CORS设置。根据Apollo文档:
提供false以完全删除CORS中间件,或提供true以使用您的中间件的默认配置。
默认值为真。
为了解决这个问题,我只需要在Apollo中禁用CORS功能,这只需要在.applyMiddleware中设置cors:false即可。
server.applyMiddleware({
    app,
    path: '/',
    cors: false,
});

更多参考资料:


1

我曾经遇到过类似的问题,我的Express服务在apache2代理服务器前运行。代理服务器会缓存部分响应(仅限部分响应)。为了解决这个问题,我在apache配置文件中添加了以下内容:

Header set Cache-Control "no-cache, must-revalidate"    env=no-cache-headers
Header set Pragma        "no-cache"                     env=no-cache-headers
Header set Expires       "Sat, 1 Jan 2000 00:00:00 GMT" env=no-cache-headers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接