我创建api代理并选中“为您的API启用直接浏览器访问 - 允许通过CORS从浏览器直接请求”的复选框。但我的OPTIONS请求仍然失败:
{
"fault": {
"faultstring": "Received 405 Response without Allow Header",
"detail": {
"errorcode": "protocol.http.Response405WithoutAllowHeader"
}
}
}
根据我对CORS飞行前选项请求的理解,客户端首先将OPTIONS请求发送到服务器,作为“安全”CORS的安全措施。此请求应返回一个响应,其中包含可用的请求类型列表。
我的问题:如何使Apigee正确响应OPTIONS请求,而不会将OPTIONS请求传递给代理后面的api?。如果有帮助我让AngularJS javascript应用程序试图与我的Apigee端点进行通信。
Javascript错误:
OPTIONS http://api.example.com No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://client.example.com' is therefore not allowed access.
XMLHttpRequest cannot load http://api.example.com. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://client.example.com' is therefore not allowed access.
默认“添加CORS”xml
<AssignMessage async="false" continueOnError="false" enabled="true" name="Add-CORS">
<DisplayName>Add CORS</DisplayName>
<FaultRules/>
<Properties/>
<Add>
<Headers>
<Header name="Access-Control-Allow-Origin">*</Header>
<Header name="Access-Control-Allow-Headers">origin, x-requested-with, accept</Header>
<Header name="Access-Control-Max-Age">3628800</Header>
<Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE</Header>
</Headers>
</Add>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>
默认代理端点xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
<Description/>
<Flows/>
<PreFlow name="PreFlow">
<Request/>
<Response/>
</PreFlow>
<HTTPProxyConnection>
<BasePath>/v1/cnc</BasePath>
<VirtualHost>default</VirtualHost>
<VirtualHost>secure</VirtualHost>
</HTTPProxyConnection>
<RouteRule name="default">
<TargetEndpoint>default</TargetEndpoint>
</RouteRule>
<PostFlow name="PostFlow">
<Request/>
<Response/>
</PostFlow>
</ProxyEndpoint>
默认目标端点xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TargetEndpoint name="default">
<Description/>
<Flows/>
<PreFlow name="PreFlow">
<Request/>
<Response>
<Step>
<Name>Add-CORS</Name>
</Step>
</Response>
</PreFlow>
<HTTPTargetConnection>
<URL>http://api.example.com/v1/assets.json</URL>
</HTTPTargetConnection>
<PostFlow name="PostFlow">
<Request/>
<Response/>
</PostFlow>
</TargetEndpoint>
答案 0 :(得分:7)
由于您不希望OPTIONS请求传递到后端API,因此需要做两件事:
RouteRule到具有OPTIONS请求条件的空目标。请注意,没有指定TargetEndpoint。
<RouteRule name="NoRoute">
<Condition>request.verb == "OPTIONS"</Condition>
</RouteRule>
ProxyEndpoint中的自定义流程,用于处理CORS响应。由于新的RouteRule将消息发送到空目标(将请求回送给客户端),因此消息将不会路由到当前定义CORS策略的“默认”TargetEndpoint。
您的ProxyEndpoint的更新版本如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
<Description/>
<Flows>
<Flow name="OptionsPreFlight">
<Request/>
<Response>
<Step>
<Name>Add-CORS</Name>
</Step>
</Response>
<Condition>request.verb == "OPTIONS"</Condition>
</Flow>
</Flows>
<PreFlow name="PreFlow">
<Request/>
<Response/>
</PreFlow>
<HTTPProxyConnection>
<BasePath>/v1/cnc</BasePath>
<VirtualHost>default</VirtualHost>
<VirtualHost>secure</VirtualHost>
</HTTPProxyConnection>
<RouteRule name="NoRoute">
<Condition>request.verb == "OPTIONS"</Condition>
</RouteRule>
<RouteRule name="default">
<TargetEndpoint>default</TargetEndpoint>
</RouteRule>
<PostFlow name="PostFlow">
<Request/>
<Response/>
</PostFlow>
</ProxyEndpoint>
注意:RouteRule按ProxyEnpoint配置中指定的顺序进行评估。您应始终在最后具有默认(无条件)路由。否则,如果在顶部,它将始终匹配并且从不评估其他路线可能性。
答案 1 :(得分:0)
我做了上面答案中提到的同样的事情,但是仍然遇到同样的问题。然后解决了一些研究问题。
问题是在请求期间未将cors标头响应作为标头传递。要解决这个问题,您还可以在代理端点预流程中添加cors值:
<PreFlow name="PreFlow">
<Request/>
<Response>
<Step>
<Name>Add-CORS</Name>
</Step>
</Response>
</PreFlow>