跨域禁飞前选项禁止

时间:2014-02-04 21:48:48

标签: php jquery apache codeigniter cors

更新了代码并进一步降低原因


我正在构建一个能够与Phil Sturgeons code igniter rest application通信的客户端应用程序。

问题是,在尝试请求登录方法时,OPTIONS http://site/api/login 403 (Forbidden)OPTIONS http://site/api/login Invalid HTTP status code 403提示我。

我已经在服务器和Apache级别启用了CORS,希望它可能会更改响应消息。在application/config/config.php

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS');
header('Access-Control-Allow-Headers: X-API-KEY, X-AUTH-TOKEN');
// header('Access-Control-Allow-Methods: OPTIONS, true, 200'); <- tried this also

httpd.conf

中的Apache级别
Header always set Access-Control-Allow-Origin "*"                   
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, PUT, DELETE"

jQuery代码,我已经注释了以前发送不同标头的方法。如果未指定X-API-KEY,则会返回相应的错误 {"status":false,"error":"Invalid API Key."}

$.ajax({
    type: "POST",
    url: "http://site/api/login",
    data: {data : encrypted_login},
    headers: {"X-API-KEY": "_API_KEY_"},
    // headers: {"X-API-KEY": "_API_KEY_", "Content-Type":  "application/x-www-form-urlencoded"},
    // beforeSend: function( xhr ) {
        // xhr.overrideMimeType( "application/x-www-form-urlencoded;" );
        // xhr.setRequestHeader('X-API-KEY', '_API_KEY_');
        // xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;');
        // Tried different Content-Types to try avoid the pre-flight call
    // },
    // crossDomain: true,
    // dataType: 'json',
    success: function(data) {
       console.log('success' + data); // show response from the php script.
    },
    error: function(XMLHttpRequest, textStatus, errorThrown){
        alert(errorThrown); // throws empty
    },
    fail: function(data) {
        console.log('fail login : ',data);
    }
});

随着对OPTION的其余库支持的最新更新,添加了PATCH和HEAD。我写了一个方法,可以容纳总是返回200的登录选项调用。遗憾的是,这并没有改变这种情况。

function login_options(){
    $this->response(array('response' => 'Hello World!'), 200);
}

注意:使用POSTMAN chrome扩展程序时,包括login_options在内的所有调用都能正常运行。

编辑:与Phil Sturgeons图书馆否认它有关,网站的根目录接受飞行前请求。使用3.0.0-pre构建版本

编辑:与将标头传递给请求有关。如果没有这个,并且禁用了API密钥,它就可以工作。




更新

问题是由于使用虚拟主机名。为什么会发生这种情况我不确定,我已经在2台不同的机器上进行了3次Phil Sturgeons rest server的空白分期测试,并能够在所有这些机器上复制问题。

我如何设置虚拟主机无关紧要,我尝试了这两种方法。

我的httpd-vhosts.conf

<VirtualHost *>
DocumentRoot "/Users/admin/Sites/rest_library"
ServerName rest_library
ErrorLog "/private/var/log/apache2/rest_library-error_log"
CustomLog "/private/var/log/apache2/rest_library-access_log" common
<Directory "/Users/admin/Sites">
    AllowOverride All
    Options Indexes FollowSymLinks MultiViews
    Order allow,deny
    Allow from all
</Directory>
</VirtualHost>

兼容httpd-vhosts.conf

<VirtualHost *:80>
  ServerName restserver
  DocumentRoot "/Users/admin/Sites/codeigniter-restserver"
  DirectoryIndex index.php
  <Directory "/Users/admin/Sites/codeigniter-restserver">
    AllowOverride All
    Allow from All
  </Directory>
</VirtualHost>

为了解决这个问题,我必须将所有内容引用为http://localhost/rest_library/api/。这也发生在使用CNAMES的服务器上,尚未测试顶级站点。使用完全相同的代码,我能够使非虚拟主机工作,而具有虚拟主机的那个失败。

另外,因为在设置Access-Control-Allow-Headers时你无法将Access-Control-Allow-Credentials设置为通配符我使用了一种不太可靠的方法来解决这个问题

header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

我在另一个Stack Overflow线程中找到了答案,它确实有效!

你需要检测方法,如果它的OPTIONS然后通过die()退出php!

信用:replace