Wulung Triyanto
Wulung Triyanto

Reputation: 347

CORS blocked when invoking 3rd party API wrapped with Azure API Management

I have an issue that has been bothering me for almost 1 month. I'll be honest, I am not front end developer. So here is the issue.

I have a Azure API Management that wrap 3rd party maps provider. That APIM consumed by front end developed with React.js + Axios. Every time the front end invoke API that wrapped with Azure APIM, it will be resulted error with detail:

enter image description here

enter image description here

enter image description here

Access to XMLHttpRequest at [APIM URL] from origin [FE ORIGIN] has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Here is my Azure APIM policy that implemented on all operation:

    <policies>
    <inbound>
        <base />
        <cors allow-credentials="false">
            <allowed-origins>
                <origin>[FE ORIGIN]</origin>
                <origin>http://localhost:3000/</origin>
                <origin>http://localhost:3001/</origin>
            </allowed-origins>
            <allowed-methods preflight-result-max-age="300">
                <method>GET</method>
                <method>POST</method>
                <method>DELETE</method>
                <method>OPTIONS</method>
                <method>PUT</method>
            </allowed-methods>
            <allowed-headers>
                <header>content-type</header>
                <header>accept</header>
                <header>transactionId</header>
                <header>authorization</header>
                <header>userId</header>
                <header>oid</header>
                <header>userRoles</header>
            </allowed-headers>
        </cors>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
        <set-header name="Access-Control-Allow-Origin" exists-action="override">
            <value>@(context.Request.Headers.GetValueOrDefault("Origin",""))</value>
        </set-header>
        <set-header name="Access-Control-Allow-Credentials" exists-action="override">
            <value>false</value>
        </set-header>
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

And here is the part of Axios code:

  const handleSearch = useMemo(() => {
    const searchHandler = (value: string) => {
      if (value.length >= DELAY_CHAR) {
        const searchUrl = `${BASE_URL}?q=${value}&at=-0.789275,113.921327&limit=${MAX_ROW}`;
        axios
          .get(searchUrl)
          .then((res) => {
            const { items } = res.data;
            if (items && items.length > 0) {
              const opts: Opts[] = [];
              items.forEach((r) => {
                opts.push({
                  position: r.position,
                  value: r.address.label,
                });
              });
              setOptions(opts);
            }
          })
          .catch(() => {
            return null;
          });
      }
    };
  
    return debounce(searchHandler, DELAY_IN_MS);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [DELAY_IN_MS]);

I've try many options even wrapping the 3rd party API in newly created API. So I any helps really means a lot to me. Thank you very much before and I hope the information is enough.

Upvotes: 0

Views: 319

Answers (1)

Wulung Triyanto
Wulung Triyanto

Reputation: 347

So, after hours spend for trial and errors, we've finally find the root cause. Notice the <base /> on <inbound> part, we remove that part and viola, it success. I'll be honest I don't understand why but it solve the issue. Here is the final inbound policy:

<policies>
<inbound>
    <!--<base />-->
    <cors allow-credentials="false">
        <allowed-origins>
            <origin>[FE ORIGIN]</origin>
            <origin>http://localhost:3000/</origin>
            <origin>http://localhost:3001/</origin>
        </allowed-origins>
        <allowed-methods preflight-result-max-age="300">
            <method>GET</method>
            <method>POST</method>
            <method>DELETE</method>
            <method>OPTIONS</method>
            <method>PUT</method>
        </allowed-methods>
        <allowed-headers>
            <header>content-type</header>
            <header>accept</header>
            <header>transactionId</header>
            <header>authorization</header>
            <header>userId</header>
            <header>oid</header>
            <header>userRoles</header>
        </allowed-headers>
    </cors>
</inbound>
<backend>
    <base />
</backend>
<outbound>
    <base />
    <set-header name="Access-Control-Allow-Origin" exists-action="override">
        <value>@(context.Request.Headers.GetValueOrDefault("Origin",""))</value>
    </set-header>
    <set-header name="Access-Control-Allow-Credentials" exists-action="override">
        <value>false</value>
    </set-header>
</outbound>
<on-error>
    <base />
</on-error>
</policies>

Upvotes: 0

Related Questions