CORS预检请求返回"403 Forbidden"; 后续请求然后仅在Chrome中发送

dun*_*unc 4 php iis jquery http-headers cors

这个问题中使用pluploader失败后,我现在正在尝试FineUploader.

在阅读了CORS之后,我在IIS6服务器上实现了各种标头.

似乎发生的事情是我的脚本触发了第一个(preflight)授权请求,该请求失败了,但Chrome允许第二个(standard)请求无论如何都要发送 - Firefox没有.我认为这实际上是代表Chrome的一个错误,但至少它让我能够确定我的脚本可能正常工作.

这是Chrome和FF中的第一个(预检)请求:

OPTIONS /frog/LOTS/upload/php.php HTTP/1.1
Host: staff.curriculum.local
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:14.0) Gecko/20100101 Firefox/14.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Origin: http://frogserver.curriculum.local
Access-Control-Request-Method: POST
Access-Control-Request-Headers: cache-control,x-requested-with
Pragma: no-cache
Cache-Control: no-cache
Run Code Online (Sandbox Code Playgroud)

Access-Control...标题是我添加到IIS 的标题.

以下是我的回复标题:

HTTP/1.1 403 Forbidden
Content-Length: 1758
Content-Type: text/html
Server: Microsoft-IIS/6.0
x-powered-by: ASP.NET
Access-Control-Allow-Origin: http://frogserver.curriculum.local
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Cache-Control
Access-Control-Allow-Methods: OPTIONS, GET, POST
Access-Control-Expose-Headers: Origin, X-Requested-With
Date: Mon, 22 Apr 2013 15:19:20 GMT
Run Code Online (Sandbox Code Playgroud)

我试图比较两个并排,但我找不到任何丢失的标题,这将导致preflight请求返回403 Forbidden错误.

403禁止

我没有包含我的PHP源代码,因为它是很多代码.可以说它在Chrome中运行并且文件已正确上传,因此脚本应该是正确的.唯一可能值得一提的是,header("Content-Type: text/plain");我的脚本开头就有了.更改text/html它对Chrome和FireFox没有任何影响.

JavaScript很简单:

$('#jquery-wrapped-fine-uploader').fineUploader({
    request: {
        endpoint: 'http://staff.curriculum.local/frog/LOTS/upload/php.php'
    },
    cors: {
        expected: true, //all requests are expected to be cross-domain requests
        sendCredentials: true //if you want cookies to be sent along with the request
    }
});
Run Code Online (Sandbox Code Playgroud)

有人可以帮忙吗?今天我已经花了8个小时来处理这个单一的问题而且我已经<离我自己的脸了......

提前致谢,

Ray*_*lus 5

正如我的评论中提到的,这似乎是您的服务器的问题.出于某种原因,它拒绝了初始的OPTIONS请求.您需要查看服务器日志,以了解服务器使用403响应此请求的原因.

用户代理发送此初始OPTIONS(飞行前)请求.Fine Uploader不直接发送此请求,用户代理将其发送以符合CORS规范.如果您对CORS有特定问题,可以看一下我的博客文章,了解Fine Uploader如何处理CORS,或者/你可以阅读这篇关于CORS的优秀MDN文章.


dun*_*unc 3

我花了一个星期的时间,终于找到了问题所在。

默认情况下,IIS6 不支持 .php 文件(或 .asp(x))上的 OPTIONS 动词。

因此,它OPTIONS根本无法识别飞行前呼叫。

要在 IIS6 中更改此值,请按照下列步骤操作:

  1. 在 IIS 管理器中,转到您的网站根目录。右键单击它并选择“属性”
  2. 转到主目录选项卡,然后选择底部的“配置”按钮
  3. 找到您尝试与之通信的脚本的相关文件扩展名,例如 .php 或 .asp,然后单击“编辑”
  4. 添加OPTIONS到可用动词列表(现在应该显示类似的内容REQUEST, GET, POST, OPTIONS
  5. 将以下代码添加到您的 PHP 脚本中以确定来自 IE 的响应

如果我的 PHP 脚本中没有以下代码,我将无法使 Internet Explorer 正常工作:

/* Is the request from Internet Explorer? */
if( !isset( $_SERVER['HTTP_X_REQUESTED_WITH'] )
    || ( isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] != "XMLHttpRequest" ) ) {

    /* If so, we need to send a UUID and iframe XSS response script... */
    header("Content-Type: text/html");

    /* This needs some extra security, for sure */
    if( $result["success"] == "true" )
        $result["uuid"] = $_POST["qquuid"];

    echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);
    echo "<script src='iframe.xss.response-3.4.1.js'></script>";
} else {
    /* Otherwise, we can just echo the json'd result */
    echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);
}
Run Code Online (Sandbox Code Playgroud)

我给了 Ray Nicholus 50 分的赏金,虽然我没有发现他的态度特别有帮助,但他一直都是对的。但是,为了其他人查看这篇文章时遇到类似问题,我会将我的答案标记为正确。