【问题标题】:CORS Error: What is the correct way to configure Symfony 5 to accept CORS?CORS 错误:配置 Symfony 5 以接受 CORS 的正确方法是什么?
【发布时间】:2021-05-19 07:52:40
【问题描述】:

目标

我正在尝试从 Vue 3 打字稿前端向 Symfony 5 API 发送请求。使用NelmioCorsBundle 请求在 Insommia(邮递员)中有效,但在 Chrome、Safari 和 Firefox 中无效。

错误

CORS 策略已阻止从源“http://localhost:8080”获取“https://localhost:8000/api/users/6”的访问权限:对预检请求的响应未通过访问控制检查:请求的资源上不存在“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
      }
    })
  }
}

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

在 .env 文件中,CORS_ALLOW_ORIGIN 是这样定义的:

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

我的尝试

  1. 我尝试在 NelmioCorsBundle 和 index.php 中设置 Access-Control-Allow-Origin 标头
  2. 我已尝试将 'http://localhost:8080' 作为 allow_origin。
  3. 我尝试在 index.php 文件中务实地设置不同的标头,结果却陷入了一个错误的兔子洞。
  4. 我还尝试了文档中关于 How to ignore preflight requests on New Relic? 的建议,此 FilterResponseEvent 类不存在(因此重新安装了 NelmioCorsBundle,但没有效果。)

【问题讨论】:

    标签: php symfony cors


    【解决方案1】:

    您好,它工作正常,我使用 axios 和 ReactJs 的前端。

    nelmio_cors.yaml

    nelmio_cors:
        defaults:
            origin_regex: true
            allow_origin: ['*']
            allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
            allow_headers: ['*']
            expose_headers: ['Link']
            max_age: 3600
        paths:
            '^/': ~
    

    .env

    ###> nelmio/cors-bundle ###
    CORS_ALLOW_ORIGIN=^.*$
    ###< nelmio/cors-bundle ###
    

    【讨论】:

      【解决方案2】:

      在与 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();
      }
      

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

      【讨论】:

      • 哈哈!爱它!我现在只是在尝试。 yourdomain 占位符是本地地址吗?
      • @KerrialBeckettNewham 你是对的,yourdomain 是一个占位符,你应该把你真正的生产网络域放在那里。使用本地开发服务器时,允许的来源将始终是请求的来源!
      • 不幸的是,现在又出现了另一个错误:CORS 策略已阻止从源“localhost:8080”获取“localhost:8000/api/users/6”的访问权限:“Access-Control-Allow-Origin”标头包含多个值 'localhost:8080, localhost:8080',但只允许一个。让服务器发送带有有效值的标头,或者,如果不透明的响应满足您的需要,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。
      • @KerrialBeckettNewham 很奇怪,它一定与您的设置有关。确保$_SERVER['HTTP_REFERER'] 的值是应有的值,并且只发回一个Access-Control-Allow-Origin: 标头。您是否禁用了之前的 nelmio 安装?
      • 我无法为您提供更多关于这些信息的帮助,但如果我必须给您一条建议,那就是充分利用您的开发工具来了解问题的根本原因你有:)
      【解决方案3】:

      您好,您能否尝试在 NelmioCorsBundle 中将路径从 '^/' 更改为 '^/api/' 并添加此配置,如下例所示:

      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:
              '^/api/':
                  allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
                  allow_headers: ['X-Custom-Auth', 'Content-Type', 'Authorization', 'Location']
                  allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTION']
                  expose_headers: ['Link', 'Location']
                  max_age: 3600
      

      【讨论】:

      • 谢谢,我之前试过(重新安装了 NelmioCorsBundle,因此 nelmio_cors.yaml 开箱即用),然后又试了一次。不用找了。 :'(
      猜你喜欢
      • 1970-01-01
      • 2021-05-03
      • 2019-11-19
      • 2019-06-26
      • 2012-09-03
      • 2021-07-17
      • 2023-03-26
      • 2021-06-06
      • 2023-03-23
      相关资源
      最近更新 更多