Hello Team,
We have created an API Proxy using No-Target and added CORS in Assign Message policy. When testing API Proxy with POST method in developer portal, got a CORS error i.e., Unknown Status
{ “isTrusted”: true } .
In Assign Message Policy we have added the following code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
ADD CORS
*
origin, x-requested-with, accept,Authorization
3628800
GET
true
true
Thanks in Advance
Hi Lakshmi, can you provide the full error shown in browser developer tools(F12 >> Console)
Make sure your are responding to the OPTIONS request, that happens before any other new request
1 Like
Try to add “content-type” header to Access-Control-Allow-Headers.
Like this
<Header name="Access-Control-Allow-Headers">origin, x-requested-with, accept, content-type</Header>
It helped me.
In the “Access-Control-Allow-Headers”, add “Authorization”
In the response also include POST and other verbs.
<Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE</Header>
Also, may want to include the origin and request headers automatically, as you might in a shared flow.
For example to get all the request headers and assign to a variable:
/* globals context, request */
/**
* This script reads all values of the multi-valued request header Access-Control-Request-Headers
* and sets them as a CSV in the flow variable accessControlRequestHeaders.
*
* Use this script because there seems to be no direct way to get the
* values of a multi-valued header directly in out-of-the-box policies
*/
// Variable to hold value of flow variable accessControlRequestHeaders.
var accessControlRequestHeadersAsCsv = "";
// Copy all values of the header Access-Control-Request-Headers.
var valueCount = request.headers["Access-Control-Request-Headers"].length();
for(var i = 0; i < valueCount; i++) {
accessControlRequestHeadersAsCsv += request.headers["Access-Control-Request-Headers"][i];
if( i+1 !== valueCount ) {
accessControlRequestHeadersAsCsv += ",";
}
}
// Set as flow variable.
context.setVariable("accessControlRequestHeaders", accessControlRequestHeadersAsCsv);
Then in your Assign Message to add CORS
<AssignMessage async="false" continueOnError="false" enabled="true" name="AM-add-CORS">
<DisplayName>AM-add-CORS</DisplayName>
<Add>
<Headers>
<Header name="Access-Control-Allow-Origin">{request.header.origin}</Header>
<Header name="Access-Control-Allow-Headers">{accessControlRequestHeaders}</Header>
<!-- Set to a larger value in seconds, this allows for testing -->
<Header name="Access-Control-Max-Age">60</Header>
<Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE</Header>
<Header name="X-CORS">true</Header>
</Headers>
</Add>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>
1 Like
Here’s a cleaner way to get all the values in a multi-valued header, as would be the case for Access-Control-Allow-Headers. It uses the newly released Message Template Functions.
<AssignMessage async="false" continueOnError="false" enabled="true" name="AM-add-CORS">
<DisplayName>AM-add-CORS</DisplayName>
<Add>
<Headers>
<Header name="Access-Control-Allow-Origin">{request.header.origin}</Header>
<Header name="Access-Control-Allow-Headers">{substring(request.header.Access-Control-Request-Headers.values,1,-1)}</Header>
<!-- Set to a larger value in seconds, this allows for testing -->
<Header name="Access-Control-Max-Age">60</Header>
<Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE</Header>
<Header name="X-CORS">true</Header>
</Headers>
</Add>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>
hey guys, I implemented something like that and it served me correctly.
In the proxy enpoint we must place in the preflow the next call of a Flowcallout to invoke a sharedflow which will have the policy of CORS
FC-CORS
FC-OAuth2
Definition of flowcallout, where we invoke the sharedflow
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
FC-CORS
OPTIONS-CORS-Headers-Response
definition of sharedflow
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
OPTIONS-CORS-Headers-Response
request.verb == "OPTIONS"
definition of the policy of raisefull, where we will indicate the headers of Access-Control-Allow-Origin with * that will allow the invocation from our browser
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
OPTIONS CORS Headers Response
*
origin, x-requested-with, accept, ucsb-api-key, ucsb-api-version, authorization
3628800
GET, PUT, POST, DELETE
200
OK
true
angular:
const httpOptions2= { headers:newHttpHeaders({ ‘Authorization’:‘Bearer token’ }) };
obtenerCatalogos():Observable { return this.httpClient.get(uriApigee+‘endpointapigee’,httpOptions2); }
Regars
Be warned, using RaiseFault with 200 will still be recorded as an error in analytics.
I’ve created a feature request to have “return immediately” or “interrupt” functionality added to Assign Message to support this use case.
Also, note that you will need to add CORS to any true fault responses.
Have you used CORS in shared flow and can you attach proxy code please. I am facing error
Access to fetch at ‘https://mmmmmm.ccccom’ from origin ‘https://xxx.xxx.com’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.
Here’s an example Shared Flow that may help.
https://github.com/kurtkanaskie/CORS-Shared-Flow
FYI, a new CORS policy that handles everything is being developed.