Reputation: 347
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:
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
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