背景和问题
我目前正在 ezPlatform 和 Symfony 之上构建一个 Web 应用程序。
我现在的目标是使用 JS 客户端从外部网站请求此应用程序(使用 ezplatform 的 JS REST 客户端:CAPI.js)
我在本地测试了我的脚本(在应用程序本身 = 同一个域上),一切都很好:我可以 GET 和 POST 数据。
但是在外部网站(CORS 请求)上测试这个脚本没有用。我遇到了两个不同的问题:
- 服务器端:响应标头不包含 Access-Control-Allowed-Methods
- 客户端:请求中没有提供会话 cookie
细节
问题 1:没有标题“allow_methods”
在 chrome 上我总是有这个错误:
XMLHttpRequest cannot load http://api.ezplatform.lan/api/ezp/v2/user/sessions. Response for preflight has invalid HTTP status code 405
请注意,在服务器端,nelmio_cors包用于配置标头。配置:
nelmio_cors:
paths:
'^/api/ezp/v2/':
max_age: 3600
allow_credentials: true
allow_origin: ['*']
allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
expose_headers: []
现在,这里是失败的预检请求的详细信息:
GENERAL
Request URL:http://api.ezplatform.lan/api/ezp/v2/user/sessions
Request Method:OPTIONS
Status Code:405 Method Not Allowed
Remote Address:192.168.1.82:80
REPONSE HEADERS
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:authorization, accept, content-type, x-csrf-token, destination, x-siteaccess
Access-Control-Allow-Origin:http://www.externalsite.lan
Access-Control-Max-Age:3600
Cache-Control:private
Connection:Keep-Alive
Content-Length:0
Content-Type:text/html; charset=UTF-8
Date:Tue, 13 Dec 2016 15:24:44 GMT
Keep-Alive:timeout=5, max=99
Server:Apache/2.4.23 (Ubuntu)
Vary:X-User-Hash
REQUEST HEADERS
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Cache-Control:no-cache
Connection:keep-alive
Host:api.ezplatform.lan
Origin:http://www.externalsite.lan
Pragma:no-cache
Referer:http://www.externalsite.lan/
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
在“响应标题”中,Access-Control-Allow-Methods
尽管有 nelmio_cors 配置,但没有。
挖掘 nelmio_cors 代码,我意识到“allow_methods”配置已被检索,但随后被其他内容覆盖,在这里它对我来说变得模糊不清。
这个旧的 ezpublish 错误可能会给我一个有关情况的线索:ezPublishRestBundle似乎没有找到任何“允许的方法”,并且以某种方式覆盖了 nelmio_cors 配置。
在 Resprovider.php 文件中,如果我强制方法getAllowedMethods返回 this :
return ["POST", "PUT", "GET", "DELETE", "OPTIONS"];
那么我没有更多405 error
但非常不同的问题(在此之后解释)
问题 2:不允许会话 cookie
通过我之前的精彩 hack,我现在可以更进一步:我的请求被允许,但其中一些仍然失败。
我注意到请求内部没有传递会话 cookie(这是同一域上的正常行为测试)。
这一次它似乎来自 CAPI.js 文件:该XmlHttpRequest
对象从不具有withCredentials
true 属性。
如果我XHR.withCredentials = true;
在发送请求之前在 CAPI.js 中添加此代码,那么它似乎没问题。
结论
我真的很想知道ez Platform rest客户端是否设计用于跨域,但如果不是,那将是非常令人惊讶的。
所以我必须做错事,如果有人能解释一下,我会非常感激:)