当前位置: 首页 > 面试题库 >

由于CORS,Azure网站上的HTTP OPTIONS请求失败

狄珂
2023-03-14
问题内容

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

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

我已经使用以下标头已有两年了,因此,我很确定问题不在PHP代码中:

<?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网站允许的控制非常少。


问题答案:

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

1.添加<customHeaders><httpProtocol>web.config中

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

<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提供的解决方案)是删除OPTIONSVerbHandlerIIS中定义的默认值,并设置一个PHP54_via_FastCGI接受附加HTTP方法的自定义处理程序。默认处理程序仅适用于GET,POST和HEAD请求。

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

3.删除通过您的应用程序代码设置的所有响应标头

这是造成最多问题的难题的最后一部分。由于IIS已经添加了<customHeaders>,所以我在上面的问题中共享的PHP代码段正在复制它们。这在浏览器级别引起了问题,该问题无法对相同类型的多个标头做出很好的响应。

最终web.config解决了这个问题

<?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>

注意 :虽然@hcoat和@Bing Han的答案在此问题中都很有用,但我只能将其中的一项奖励。我决定将其交给@Bing
Han,因为他的回答使我离解决方案最近(而且我无法通过自己的搜索找到添加自定义PHP处理程序的html" target="_blank">方法)。

更新 :我已经编辑了答案,以添加对HTTP DELETE方法的支持以及原始答案中缺少的支持。



 类似资料:
  • 在调试我遇到的CORS问题时,我发现了以下行为。Chrome发出以下选项预检请求(由Chrome本身在CURL中重写): 以下情况下服务器对此请求的响应: 是响应“无效CORS请求”的主体。如果我重复该请求,删除标头“Access Control request Method”(仅该标头),则OPTIONS请求将成功,并得到以下响应: 然而,有问题的头是CORS规范标准头,所以它不应该阻止请求成功

  • 问题内容: 我在SO和不同的博客上都看到了数十个问题,这些问题都用“答案”来讨论-都无济于事。 我的本地机器(Ubuntu 16.04)上有一个React.js应用程序。在本地,我尝试通过运行对其进行测试,然后它将浏览器打开到http:// localhost:3000。 在一页上,我试图访问共享托管服务器上的PHP api。 Chrome和Firefox都说由于服务器没有失败。 确切消息: 但是

  • 我遇到了以下问题:在起飞前的OPTIONS请求成功后,随后的POST请求失败。这有点违反直觉,因为一旦选项成功,随后的请求应该被接受。 流程如下: 响应头 后请求 发布响应(通知是返回200,我实际上看到了结果内容,所以后端可以请求) 错误消息 请求的资源上不存在“Access Control Allow Origin”标头。起源'http://localhost:4200因此,不允许访问。

  • 问题内容: 我正在尝试在Azure网站上使用NPM运行一些预部署任务(单元测试等),但是VM上的节点版本为v0.10.32,当前节点版本为v4.2.4。 我没有通过SCM网站对命令行的非管理访问权限,没有RDP等。 有什么办法升级吗? 问题答案: 您可以使用package.json文件指定运行应用程序的节点的版本。加: 例如: 更多信息:https : //azure.microsoft.com/

  • ✔加200积分响应期权法 ✔将Access-Control-Allog-Headers,Access-Control-Allog-Methods,Access-Control-Allog-Origin方法响应头添加到OPTIONS ✔将Access-Control-Allow-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Ori

  • 问题内容: 我正在使用NodeJS 请求-简化的HTTP客户端 我似乎在使用HTTPS网站时遇到问题,但没有得到结果。 在Postman上测试了API端点(我不能共享),我只是关闭了SSL,它起作用了,我该如何使用请求插件做同样的事情? 问题答案: 只需添加以下行: 因此,您的代码如下所示: