首页 > 解决方案 > 随机发生,预检响应缺少允许标头

问题描述

这个常见错误是随机发生的:

OPTIONS https://api.cloudfunctions.net/api/graphql 404
Access to fetch at 'https://api.cloudfunctions.net/api/graphql' from origin 'https://website.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

我拥有的是一个带有部署在 Google Cloud Functions 上的 apollo 服务器和一个 react 客户端的 graphql 端点。在某些时候,客户端会在浏览器上抛出错误,但如果我尝试刷新或再次发送请求 2 或 3 次,它将起作用。

正在发送的预检请求标头:

:authority: api.cloudfunctions.net
:method: OPTIONS
:path: /api/graphql
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9,id;q=0.8,ms;q=0.7
access-control-request-headers: content-type
access-control-request-method: POST
origin: https://website.com
referer: https://website.com/
sec-fetch-mode: cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36

预期响应

access-control-allow-credentials: true
access-control-allow-headers: content-type
access-control-allow-methods: POST,OPTIONS
access-control-allow-origin: https://website.com
alt-svc: quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000
content-length: 0
content-type: text/html
date: Wed, 08 Jan 2020 00:38:16 GMT
function-execution-id: 84et92k6mvd9
server: Google Frontend
status: 200
vary: Origin, Access-Control-Request-Headers
x-cloud-trace-context: 95d25375171148a66bc629cc41a79d05
x-powered-by: Express

随机失败响应

alt-svc: quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000
cache-control: private
content-encoding: gzip
content-length: 140
content-security-policy: default-src 'none'
content-type: text/html; charset=utf-8
date: Wed, 08 Jan 2020 00:38:05 GMT
function-execution-id: 84etgky3im1k
server: Google Frontend
status: 404
x-cloud-trace-context: 77040d2c72304cad0d645480b6814f7f;o=1
x-content-type-options: nosniff
x-powered-by: Express

看看上面失败的响应,与成功的响应相比,它缺少标题是有道理的access-control-allow-*,但我再次不确定这是怎么发生的。

这是我的cors配置:

const corsConfig = {
  origin: ['https://website.com', 'http://localhost:3000'],
  methods: ['POST', 'OPTIONS'],
  credentials: true,
  optionsSuccessStatus: 200,
}

const app = express()
app
  .use(cors(corsConfig))
  .use(...)

...

apolloServer.applyMiddleware({ app, cors: corsConfig })

根据周围的一些建议,我尝试了不同的设置,但有时仍然会发生错误:

所有这一切都像十分之一一样发生,有时是在用户打开网站后的第一次请求,而其他时间是在用户浏览网站一段时间后。

标签: reactjsexpresscorsgoogle-cloud-functionsapollo-server

解决方案


我认为可能还有其他中间件会破坏您的cors设置。

您可以尝试为graphql端点使用不同的路径,并cors仅应用于该路径。

apolloServer.applyMiddleware({ app, path: '/graphql', cors: corsConfig });

或者,您可以尝试 express cors中间件并从 apollo 服务器禁用 cors


推荐阅读