CORS 错误:配置 Symfony 5 接受 CORS 的正确方法是什么?

Ker*_*ham 4 php cors symfony

客观的

我正在尝试从 Vue 3 typescript 前端发送请求到 Symfony 5 API。使用NelmioCorsBundle该请求在 Insommia (postman) 中有效,但在 Chrome、Safari 和 Firefox 中无效。

错误

从源“http://localhost:8080”获取“https://localhost:8000/api/users/6”的访问已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:否请求的资源上存在“Access-Control-Allow-Origin”标头。如果不透明响应满足您的需求,请将请求模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。

前端请求(Vue):

import { onMounted, ref } from 'vue'
import { useStore } from 'vuex'

export default {
  name: 'Home',
  setup () {
    const message = ref('Please login...')
    const store = useStore()

    onMounted(async () => {
      try {
        const response = await fetch('https://localhost:8000/api/users/6', {
          headers: { 'Content-Type': 'application/json' },
          credentials: 'include'
        })

        console.log(response)
        const user = await response.json()
        message.value = `Hello ${user.name}`
        await store.dispatch('setAuth', true)
      } catch (e) {
        console.log(e)
      }
      return {
        message
      }
    })
  }
}
Run Code Online (Sandbox Code Playgroud)

Symfony 中的 NelmioCorsBundle 配置:

nelmio_cors:
    defaults:
        origin_regex: true
        allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
        allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
        allow_headers: ['Content-Type', 'Authorization']
        expose_headers: ['Link']
        max_age: 3600
    paths:
        '^/': null
Run Code Online (Sandbox Code Playgroud)

在 .env 文件中,CORS_ALLOW_ORIGIN 的定义如下:

CORS_ALLOW_ORIGIN='^http?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
Run Code Online (Sandbox Code Playgroud)

我的尝试

  1. 我尝试在 NelmioCorsBundle 和 index.php 中设置 Access-Control-Allow-Origin 标头
  2. 我已尝试使用“http://localhost:8080”作为allow_origin。
  3. 我尝试在index.php 文件中务实地设置不同的标头,但最终陷入了错误兔子洞。
  4. 我还尝试了文档中关于如何忽略 New Relic 上的预检请求?此类FilterResponseEvent不存在(因此重新安装了 NelmioCorsBundle,但没有效果。)

yhu*_*420 7

在与 nelmio 斗争了一段时间后,我发现使用这个 ghetto 解决方案更容易:

public/index.php:

if ($_SERVER['APP_DEBUG']) {
    header('Access-Control-Allow-Origin:'.rtrim($_SERVER['HTTP_REFERER'], '/'));
} else {
    header('Access-Control-Allow-Origin:yourdomain');
}
header('Access-Control-Allow-Headers:*');
header('Access-Control-Allow-Credentials:true');
header('Access-Control-Allow-Headers:X-Requested-With, Content-Type, withCredentials');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    die();
}
Run Code Online (Sandbox Code Playgroud)

我在该行之后使用它bootEnv。我正在使用 symfony 5+