HTTP OPTIONS request on Azure Websites fails due to CORS

后端 未结 3 816
情歌与酒
情歌与酒 2020-11-27 21:50

I\'ve recently moved our servers from Rackspace CloudSites (running on Apache/Linux) to Windows Azure Websites. Since the migration, all the jQuery AJAX requests on our REST

相关标签:
3条回答
  • 2020-11-27 22:22

    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.

    0 讨论(0)
  • 2020-11-27 22:33

    HTTP OPTIONS request fails because the default PHP-CGI handler does not handle the "OPTIONS" verb.

    Add the following code in web.config file will solve the issue.

    <configuration>
      <system.webServer>
        <!-- 
          Some other settings 
        -->
        <handlers>
          <remove name="OPTIONSVerbHandler" />
          <remove name="PHP54_via_FastCGI" />
          <add name="PHP54_via_FastCGI" path="*.php" verb="GET,HEAD,POST,OPTIONS" modules="FastCgiModule" scriptProcessor="D:\Program Files (x86)\PHP\v5.4\php-cgi.exe" resourceType="Either" />
        </handlers>
      </system.webServer>
    </configuration>
    

    I have a blog post on this: http://tekblg.blogspot.sg/2013/09/azure-websites-php-cross-domain-request.html

    0 讨论(0)
  • 2020-11-27 22:45

    On a windows server you can not rely on php headers for CORS. You need to create web.config in the site root or application root containing something like the following.

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
     <system.webServer>
       <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="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>
     </system.webServer>
    </configuration>
    

    This process is comparable to setting up an .htaccess file, the point being the that you can just create it where you need without reconfiguring the your server.

    0 讨论(0)
提交回复
热议问题