【发布时间】:2018-11-07 22:09:01
【问题描述】:
我的 symfony 4.1 API 有一些问题:
我正在使用 angular httpclient 通过离子应用程序使用我的 API。
我的问题在于 CORS 标头,尤其是 Access-Control-Allow-Methods
我在使用 CORS 时遇到了问题,因为我的 API 和我的应用程序不在同一个来源上,这使得我安装 nelmio/cors-bundle 来处理 CORS。
我的nelmio_cors.yaml如下:
nelmio_cors:
paths:
'^/api/':
origin_regex: true
allow_origin: ['*']
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
allow_headers: ['Content-Type', 'Authorization']
max_age: 3600
这实际上适用于我从那时起使用的所有方法:
- 发布请求 [OK]
- 获取请求 [OK]
- 删除请求 [OK]
现在我想向我的 API 添加一个 PATCH 路由。我已经用 Postman 测试了控制器,我的工作就像一个魅力。现在,当我从我的角度服务中查询相同的路线时:
return this.http.patch(this.url + '/api/users/' + userId,
dataToPatch,
this.authHeaders)
.map(response => response.json());
控制台记录以下内容:
Failed to load http://symfony.local/api/users/1: Method PATCH is not allowed by Access-Control-Allow-Methods in preflight response.
这里可以看到请求的响应头:
Access-Control-Allow-Headers: authorization,content-type
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3600
Allow: POST, GET, OPTIONS, PUT, DELETE
Cache-Control: no-cache, private
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
Date: Tue, 06 Nov 2018 14:02:51 GMT
Server: nginx
Transfer-Encoding: chunked
X-Powered-By: PHP/7.2.11
如您所见,如果我正确理解 CORS 标头,则不允许使用 PATCH 方法,但为什么在使用 postman 使用 API 时它会起作用。
我还安装了 chrome 的 Allow-Control-Allow-Origin:* 扩展,但也没有成功...
我使用https://github.com/ikamikaz3/docker-symfony 作为我的堆栈,它可以来自那里吗? (可能在某处配置错误?)
如果需要,我可以提供更多代码,但这对我来说似乎是一个愚蠢的错误......
编辑 1:
从 chrome 卸载 Allow-Control-Allow-Origin:* 后,我在登录时得到以下信息
Failed to load http://symfony.local/login_check: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'null' that is not equal to the supplied origin. Origin 'http://localhost:8100' is therefore not allowed access.
编辑 2:
在我的 nginx 容器中使用以下内容更新我的 symfony.conf 后,我设法让 API 工作,PATCH 仍然坏了,但我认为我可以做到
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
【问题讨论】:
-
“但是为什么在使用 postman 使用 API 时它会起作用” - 因为在那种情况下,CORS 甚至不适用...... Postman 不是浏览器,并且因此,一开始就没有实施任何此类限制/遵守“同源政策”。
-
啊,我明白了!我目前正在查看gist.github.com/Stanback/7145487 来解决这个问题。我还卸载了
Allow-Control-Allow-Origin:*扩展,因为我宁愿修补我的后端而不是这种解决方法