由于 CORS,Azure 网站上的 HTTP OPTIONS 请求失败 [英] HTTP OPTIONS request on Azure Websites fails due to CORS

查看:23
本文介绍了由于 CORS,Azure 网站上的 HTTP OPTIONS 请求失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近将我们的服务器从 Rackspace CloudSites(在 Apache/Linux 上运行)迁移到了 Windows Azure 网站.自迁移以来,我们 REST API 上的所有 jQuery AJAX 请求都因 CORS 开始失败.

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 API have started failing due to CORS.

我们使用自定义标头,因此 jQuery 在运行实际 API 调用之前发出 Pre-flight HTTP OPTIONS 请求.问题是 OPTIONS 请求似乎没有到达我的 PHP 代码,而是由我似乎无法控制的其他实体(显然是 Web 服务器)返回.

We use custom headers, so jQuery makes a Pre-flight HTTP OPTIONS request before running the actual API calls. The problem is that the OPTIONS request doesn't seem to reach my PHP code and is instead returned by some other entity (obviously the Web Server) which I seem to have no control over.

我已经使用以下标题几年了,所以我很确定问题不在 PHP 代码中:

I have been using the following headers for a couple of years now so I'm pretty sure the problem isn't in the PHP code:

<?php
    $this->output->set_header("Access-Control-Allow-Origin: *");
    $this->output->set_header("Access-Control-Allow-Methods: GET,POST,DELETE,HEAD,PUT,OPTIONS");
    $this->output->set_header("Access-Control-Allow-Headers: X-Olaround-Debug-Mode, Authorization, Accept");
    $this->output->set_header("Access-Control-Expose-Headers: 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" );
?>

我猜这个问题是特定于 Azure 网站的,因为代码在我的开发机器(Windows 8/IIS 8.0)上似乎也能正常工作.我是 Azure(以及一般基于 Windows 的托管)的新手,因此我几乎不知道如何处理和调试此问题,因为 Azure 网站只允许非常少的控制.

I'm guessing the problem is specific to Azure Websites since the code seems to working fine on my development machine (Windows 8 / IIS 8.0) as well. I'm new to Azure (and Windows based hosting in general) so I have almost no clue on how to approach and debug this issue since Azure Websites allow very minimal control.

推荐答案

我决定发布一个完整的解决方案来解决这个问题,因为已经提供的答案(虽然技术上是正确的)在这个特殊情况下对我不起作用.诀窍是执行以下操作:

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:

就像上面也建议的@hcoat一样,添加system.webServer.httpProtocol.customHeaders是解决问题的第一步(我之前已经自己尝试过这个,但是没有用).在此处添加您需要为 CORS 设置的所有自定义标头和 HTTP 方法.

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.覆盖 PHP 的默认处理程序并删除 OPTIONSVerbHandler

下一步(@Bing Han 提供的解决方案),是删除 IIS 中定义的默认 OPTIONSVerbHandler,并设置一个自定义 PHP54_via_FastCGI 处理程序,它接受您的额外HTTP 方法.默认处理程序仅适用于 GET、POST 和 HEAD 请求.

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)PHPv5.4php-cgi.exe" resourceType="Either" requireAccess="Script" />
</handlers>

查看这篇文章了解更多详情 关于内部运作.

这是导致最多问题的最后一块拼图.由于 IIS 已经添加了 ,因此我在上述问题中共享的 PHP 代码片段正在复制它们.这导致了浏览器级别的问题,无法很好地响应同一类型的多个标头.

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.

<?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)PHPv5.4php-cgi.exe" resourceType="Either" requireAccess="Script" />
        </handlers>
    </system.webServer>
</configuration>

注意:虽然@hcoat 和@Bing Han 的回答在这个问题上都很有用,但我只能将赏金奖励给其中之一.我决定将其提供给 @Bing Han,因为他的回答使我最接近解决方案(而且我无法通过自己的搜索找到添加自定义 PHP 处理程序的方法).

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).

更新:我已经编辑了答案以添加对 HTTP DELETE 方法的支持,这在原始答案中是缺失的.

Update: I've edited the answer to add support for HTTP DELETE method as well which was missing in the original answer.

这篇关于由于 CORS,Azure 网站上的 HTTP OPTIONS 请求失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆