HTTP OPTIONS request on Azure Websites fails due to CORS
I decided to post a complete solution to this problem since the answers already provided (while technically correct) don't work in this particular case for me. The trick was to do the following:
1. Add <customHeaders>
in <httpProtocol>
in web.config
Like @hcoat also suggested above, adding system.webServer.httpProtocol.customHeaders
was the first step to resolve the issue (I had already tried this on my own before, but it didn't work). Add all the custom headers and HTTP methods you need to set for CORS here.
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET,POST,DELETE,HEAD,PUT,OPTIONS" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Olaround-Debug-Mode, Authorization, Accept" />
<add name="Access-Control-Expose-Headers" value="X-Olaround-Debug-Mode, X-Olaround-Request-Start-Timestamp, X-Olaround-Request-End-Timestamp, X-Olaround-Request-Time, X-Olaround-Request-Method, X-Olaround-Request-Result, X-Olaround-Request-Endpoint" />
</customHeaders>
</httpProtocol>
2. Override the default handler for PHP and remove OPTIONSVerbHandler
Next step (the solution provided by @Bing Han), is to remove the default OPTIONSVerbHandler
defined in IIS, and also set a custom PHP54_via_FastCGI
handler which accepts your additional HTTP Methods. The default handler only works with GET, POST and HEAD requests.
<handlers>
<remove name="OPTIONSVerbHandler" />
<remove name="PHP54_via_FastCGI" />
<add name="PHP54_via_FastCGI" path="*.php" verb="GET, PUT, POST, DELETE, HEAD, OPTIONS, TRACE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK" modules="FastCgiModule" scriptProcessor="D:\Program Files (x86)\PHP\v5.4\php-cgi.exe" resourceType="Either" requireAccess="Script" />
</handlers>
Take a look at this post for more details on the inner workings.
3. Remove all the response headers set through your application code
This was the final piece of the puzzle that was causing the most problems. Since IIS was already adding <customHeaders>
, the PHP code snippet I shared in the question above was duplicating them. This caused problems at the browser level which didn't respond well to multiple headers of the same type.
The final web.config
that worked for this problem
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Imported Rule 1" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{R:1}" pattern="^(dir_path\.php|lolaround|lolaround\.php|app_assets)" ignoreCase="false" negate="true" />
</conditions>
<action type="Rewrite" url="lolaround.php/{R:1}" />
</rule>
<rule name="Imported Rule 2" stopProcessing="true">
<match url="lolaround/(.*)" ignoreCase="false" />
<action type="Rewrite" url="/lolaround.php/{R:1}" />
</rule>
</rules>
</rewrite>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET,POST,DELETE,HEAD,PUT,OPTIONS" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Olaround-Debug-Mode, Authorization, Accept" />
<add name="Access-Control-Expose-Headers" value="X-Olaround-Debug-Mode, X-Olaround-Request-Start-Timestamp, X-Olaround-Request-End-Timestamp, X-Olaround-Request-Time, X-Olaround-Request-Method, X-Olaround-Request-Result, X-Olaround-Request-Endpoint" />
</customHeaders>
</httpProtocol>
<handlers>
<remove name="OPTIONSVerbHandler" />
<remove name="PHP54_via_FastCGI" />
<add name="PHP54_via_FastCGI" path="*.php" verb="GET, PUT, POST, HEAD, OPTIONS, TRACE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK" modules="FastCgiModule" scriptProcessor="D:\Program Files (x86)\PHP\v5.4\php-cgi.exe" resourceType="Either" requireAccess="Script" />
</handlers>
</system.webServer>
</configuration>
Note: While both @hcoat and @Bing Han's answers were useful in this problem, I can only award the bounty to one of them. I've decided to give it to @Bing Han because his answer got me closest to the solution (and I wasn't able to find a way to add a custom PHP handler from own searching).
Update: I've edited the answer to add support for HTTP DELETE method as well which was missing in the original answer.
Azure App Service API CORS Policy not working
I have finally found the issue. When you create an API Management instance, usually you'll also need a portal for users to view your schemas, subscribe to your API and test it in the browser. To do this, once the APIM instance is created, you just have to go to the Portal Overview section and click Publish + Enable CORS, which I did for our API. What this actually does is that it sets a CORS policy with origin=Portal URL at the "All APIs" level and this policy overwrites any CORS policy you might set at an API/method level.
Unfortunately, I never considered that there might be any policies defined at the "All APIs" level so I never even clicked there. Additionally, there is no warning on the interface that one might be there nor that it overwrites policies at a lower level. Once I set the proper origin at the "All APIs" level, everything worked perfectly. Hope this helps someone with similar issues!
No 'Access-Control-Allow-Origin' header is present on the requested resource from Azure App Service API
The issue was that even though CORS was enabled in the application code, there is also a CORS page in the Azure portal where a list of origins must be added.
To find it just Search for 'CORS' in the Azure portal search bar and add the URL of the site that you would like to have access to your endpoints.
Azure APIM getting CORS error on API Post method
You should config CROS in both of your Azure app services
and APIM
.
Judging from your api settings, there should be no problem. Please check the cross-domain settings in your webapp.
For more details, you can refer below posts to locate your problems.
1. Failed to call APIs from web page behind Azure APIM due to CORS issues
2. Getting Access Control Allow Origin Error While Accessing Web Api hosted in AZURE RRS feed
Failed to call APIs from web page behind Azure APIM due to CORS issues
As @Thiago Custodio said, you should config CROS in both of your Azure app services and APIM.
Btw,if you have enabled CROS for your Azure app service , pls check you have configed CORS correctly in your APIM, based on your request, I noticed that you have a custom header : Seckey
, have you configed it in your CORS policy?
If not , pls try the CORS policy below, or you will meet CORS issue:
<cors >
<allowed-origins>
<origin>http://localhost:8080/</origin>
</allowed-origins>
<allowed-methods preflight-result-max-age="300">
<method>POST</method>
</allowed-methods>
<allowed-headers>
<header>Content-Type</header>
<header>Seckey</header>
</allowed-headers>
</cors>
Hope it helps.
Related Topics
How to Send Email from Localhost Using PHP on Linux
Separate Space-Delimited Words in a String
How to Catch a "Catchable Fatal Error" on PHP Type Hinting
How to Re-Save the Entity as Another Row in Doctrine 2
Php/Regex: How to Get the String Value of HTML Tag
Can You Re-Populate File Inputs After Failed Form Submission with PHP or JavaScript
PHP Gd Create a Transparent Png Image
Get Array's Key Recursively and Create Underscore Separated String
Array_Key_Exists Is Not Working
How to Enable MySQLi Support for PHP's Cli
Is There a Good PHP Geolocation Service
Laravel Catch Tokenmismatchexception
Send PHP HTML Mail with Attachments