我决定发布这个问题的完整解决方案,因为已经提供的答案(虽然在技术上是正确的)在这种特殊情况下对我不起作用。诀窍是执行以下操作:
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 提供的解决方案)是删除OPTIONSVerbHandler
IIS 中定义的默认值,并设置一个自定义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 处理程序的方法)。
更新:我已经编辑了答案以添加对 HTTP DELETE 方法的支持以及原始答案中缺少的方法。