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

Posted

技术标签:

【中文标题】CORS 错误:配置 Symfony 5 以接受 CORS 的正确方法是啥?【英文标题】: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]+)?$'

我的尝试

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

【问题讨论】:

【参考方案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 开箱即用),然后又试了一次。不用找了。 :'(

以上是关于CORS 错误:配置 Symfony 5 以接受 CORS 的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Symfony3 / Nelmio cors / fetch api — 400 错误请求

asp.net Core MVC 2 - 配置 CORS 以接受 NULL 来源

Express 配置为使用 CORS 不接受 CORS

不接受 S3 存储桶 CORS 配置

Symfony 4,CORS 和 OPTION 请求

CORS..Angular 和 API 平台 Symfony 的问题