CORS error on AJAX and Angular Fetch too

We are getting CORS error on the GET request from the AJAX as well as Angular fetch.

Attached is the details of the error and the proxy code is as below

CORS AssignMessage policy is as below

 

<AssignMessage name="add-cors">
  <DisplayName>Add CORS</DisplayName>
  <FaultRules/>
  <Properties/>
  <Set>
    <Headers>
      <Header name="Access-Control-Allow-Origin">*</Header>
      <Header name="Access-Control-Allow-Headers">origin, x-requested-with, accept, content-type, authorization, x-api-key, format, tenant</Header>
      <Header name="Access-Control-Max-Age">3628800</Header>
      <Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE</Header>
    </Headers>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
  <AssignTo type="response" createNew="false" transport="http"/>
</AssignMessage>

 

The proxyendpoint is:

 

<ProxyEndpoint name="default">
  <Flows>
    <Flow name="OptionsPreFlight">
      <Request/>
      <Response>
        <Step>
          <Name>add-cors</Name>
        </Step>
      </Response>
      <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
    </Flow>
  </Flows>
  <PreFlow name="PreFlow">
    <Request>
      <Step>
        <Name>RF-MissingHeaders</Name>
        <Condition>(request.header.x-api-key = null or request.header.tenant = null or request.header.format = null) and request.verb != "OPTIONS"</Condition>
      </Step>
      <Step>
        <Name>ValidateEmplid</Name>
        <Condition>request.verb != "OPTIONS"</Condition>
      </Step>
      <Step>
        <Name>EV-ValidActiveFlag</Name>
        <Condition>request.verb != "OPTIONS"</Condition>
      </Step>
      <Step>
        <Name>EV-ValidateTermEEFlag</Name>
        <Condition>request.verb != "OPTIONS"</Condition>
      </Step>
      <Step>
        <Name>RF-NoAccess</Name>
        <Condition>(ActiveeeFlag=0 and request.queryparam.file Matches "ActiveEE") OR (termeeflag=0 and request.queryparam.file Matches "TermEE") and request.verb != "OPTIONS"</Condition>
      </Step>
      <Step>
        <Name>Service-Callout-1</Name>
        <Condition>request.verb != "OPTIONS"</Condition>
      </Step>
      <Step>
        <Name>EV-DocumentID</Name>
        <Condition>request.verb != "OPTIONS"</Condition>
      </Step>
      <Step>
        <Name>GetActiveEE</Name>
        <Condition>request.verb != "OPTIONS"</Condition>
      </Step>
      <Step>
        <Name>BasicAuthPolicy</Name>
        <Condition>request.verb != "OPTIONS"</Condition>
      </Step>
    </Request>
    <!--<Response>
        <Step>
        <Name>add-cors</Name>
        <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
        </Step>
        </Response>-->
    <Response/>
  </PreFlow>
  <Flows/>
  <PostFlow name="PostFlow">
    <Request/>
    <Response/>
  </PostFlow>
  <HTTPProxyConnection>
    <BasePath>/v1/mdt</BasePath>
    <VirtualHost>secure</VirtualHost>
  </HTTPProxyConnection>
  <RouteRule name="NoRoute">
    <Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
  </RouteRule>
  <RouteRule name="test">
    <Condition>(environment.name = "non-prod-1" and request.verb != "OPTIONS")</Condition>
    <TargetEndpoint>Test</TargetEndpoint>
  </RouteRule>
  <RouteRule name="prod">
    <Condition>(environment.name = "prod-1")</Condition>
    <TargetEndpoint>Prod</TargetEndpoint>
  </RouteRule>
</ProxyEndpoint>

 

The TargetEndpoint looks like this:

 

<TargetEndpoint name="Test">
  <PreFlow name="PreFlow">
    <Request>
      <Step>
        <Name>AM-PathSuffixFalse</Name>
        <Condition>request.verb != "OPTIONS"</Condition>
      </Step>
    </Request>
    <Response>
      <Step>
        <Name>add-cors</Name>
      </Step>
    </Response>
  </PreFlow>
  <Flows/>
  <PostFlow name="PostFlow">
    <Request/>
    <Response/>
  </PostFlow>
  <HTTPTargetConnection>
    <!--<URL>https://wd2-impl-services1.workday.com/ccx/cc-blobitory/mmc8/cloud/3911747a-547e-4363-387c-75730d64742b</URL> -->
    <URL>https://wd2-impl-services1.workday.com/ccx/cc-blobitory/mmc8/{docid}</URL>
    <Properties>
      <Property name="response.streaming.enabled">true</Property>
      <Property name="request.streaming.enabled">true</Property>
      <Property name="io.timeout.millis">1800000</Property>
    </Properties>
  </HTTPTargetConnection>
</TargetEndpoint>

 

CORS.png

0 1 632
1 REPLY 1

Yes. CORS is tricky.   Your proxy is not working as you want it to, probably because you are adding the CORS headers only to the preflight response. But that's not right.  You need the headers in every response, including the preflight response.

There is a document that describes how to add CORS support to your proxies, available here.  This relies on the new(-ish) CORS policy, and works with Apigee X and Apigee hybrid. 

If you are still using Apigee Edge, then you need a slightly different approach. It is described here. Apigee Edge does not include the CORS policy, so you need to do a little extra work. But it works out to be the same. 

In either case, you need to make sure you allow the right things - maybe Credentials, maybe headers, and so on.  So take care with setting up the CORS headers properly. 

I produced a screencast on this topic not too long ago.  Find it here.