用户
 找回密码
 入住 CI 中国社区
搜索
查看: 9895|回复: 10
收起左侧

[已解决] 急求!如何允许跨域访问?

[复制链接]
发表于 2016-12-30 09:27:43 | 显示全部楼层 |阅读模式
情况是这样的:
我们的网站需要跨域访问,我查了跨域的资料,大概也了解了浏览器在发送跨域请求之前,会先发送一个Options方法过来,服务器返回可以访问的域,如果浏览器没收到被允许访问,真正的请求就不会被执行发送。所以网页就一直卡在Options请求这个地方。
然后我查了CI在跨域方面的配置,是在config.php里面有个csrf_protection的配置,默认是FALSE的。因为服务器没有禁止跨域,但是同样的也没有对网页发来的options请求进行处理,所以浏览器没收到需要的回复就无法访问。于是我将其设置为TRUE,并且在csrf_exclude_uris中加入了我需要的域名。但是仍然不行。config中那段代码修改如下:

$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_test_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 7200;
$config['csrf_regenerate'] = TRUE;
$config['csrf_exclude_uris'] = array('web.xxx.ddd.com');

之后我又尝试在routes.php中加入关于options方法的路由:

$route['item/([0-9]{1,19})']['options'] = 'BaseController/options';

仍然没有效果。

各位大神,请求帮助!!!Hex~~~~
发表于 2016-12-30 10:54:32 | 显示全部楼层
跨域是 CORS,你搞了半天 CSRF 完全是两码事。
你搜一下 PHP CORS 吧,这个就是设置几个 HTTP 头就可以了,和路由也没关系。
CORS 是一个标准,本身和 PHP 也是没关系的,建议阅读相关文档。
 楼主| 发表于 2016-12-30 11:12:20 | 显示全部楼层
Hex 发表于 2016-12-30 10:54
跨域是 CORS,你搞了半天 CSRF 完全是两码事。
你搜一下 PHP CORS 吧,这个就是设置几个 HTTP 头就可以了, ...

是加入这个头吧?

header("Access-Control-Allow-Origin: *");

这个在哪里加呢?因为这个是需要对于所有url的options方法都返回这个的,在CI里面这个应该写在哪里呢?
我之前想尝试路由的方式,就是想将所有url的options方法都映射到某个类里面的options函数,在函数里面设置这个头部,然后直接返回,代码如下:

        public function options()
        {
                header("ACCESS-CONTROL-ALLOW-ORIGIN: *");
                exit();
        }

但是还是行不通。Hex,这个header应该放在哪里呢?
发表于 2016-12-30 11:44:17 | 显示全部楼层
options 是个 HTTP method,不是 URL。
你可以把 header("ACCESS-CONTROL-ALLOW-ORIGIN: *"); 加到控制器的构造函数中,并不用关心是不是 options,所有请求都返回这个头也是没问题的。
 楼主| 发表于 2016-12-30 11:56:04 | 显示全部楼层
Hex 发表于 2016-12-30 11:44
options 是个 HTTP method,不是 URL。
你可以把 header("ACCESS-CONTROL-ALLOW-ORIGIN: *"); 加到控制器的 ...

是的,我就是在控制器中加入的。我的route是这样的:

$route['item/([0-9]{1,19})']['get'] = 'Item/get_one/$1';
$route['item/query/available']['post'] = 'Item/available';

我不想使用CI默认的那套映射逻辑,所以都是自定义路由的。现在问题就是,比如请求item/query/available,浏览器会先发一个['item/query/available']['options']过来,但是根据我的路由,找不到对应的控制器。然后我加了这条路由来处理

$route['item/query/available']['options'] = 'BaseController/options';

options函数的内容是:
        public function options()
        {
                header("ACCESS-CONTROL-ALLOW-ORIGIN: *");
                exit();
        }

然后还是无效
发表于 2016-12-30 12:19:01 | 显示全部楼层
liaow10 发表于 2016-12-30 11:56
是的,我就是在控制器中加入的。我的route是这样的:

$route['item/([0-9]{1,19})']['get'] = 'Item/get ...

给所有请求都加这个,肯定好使啊(直接在 index.php 里加这句话)
PHP复制代码
header("Access-Control-Allow-Origin: *");
复制代码

本身这个功能和 CI 是没什么关系的,你按照 PHP 的写法就可以了,不要太纠结了。


 楼主| 发表于 2016-12-30 14:25:54 | 显示全部楼层
Hex 发表于 2016-12-30 12:19
给所有请求都加这个,肯定好使啊(直接在 index.php 里加这句话)
本身这个功能和 CI 是没什么关系的,你 ...

我加了,在index.php里面,最后require_once之前加的,没有用啊,还是报错。

/*
* --------------------------------------------------------------------
* LOAD THE BOOTSTRAP FILE
* --------------------------------------------------------------------
*
* And away we go...
*/
header('Access-Control-Allow-Origin: *');
require_once BASEPATH.'core/CodeIgniter.php';

我在浏览器里面debug,错误如下:
未命名.png

XMLHttpRequest cannot load http://xxx:xx/user-item-purchase/query/search-by-user. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://xxx.com' is therefore not allowed access.

这个问题搞一天了。。
 楼主| 发表于 2016-12-30 14:32:41 | 显示全部楼层
Hex 发表于 2016-12-30 12:19
给所有请求都加这个,肯定好使啊(直接在 index.php 里加这句话)
本身这个功能和 CI 是没什么关系的,你 ...

没事了!非常感谢Hex的帮助!
一直不通的原因是同事把URL写错了,无论我如何改,他请求的都是另一个地址。。。
发表于 2016-12-30 14:34:42 | 显示全部楼层
liaow10 发表于 2016-12-30 14:32
没事了!非常感谢Hex的帮助!
一直不通的原因是同事把URL写错了,无论我如何改,他请求的都是另一个地址 ...

别客气。

诡异的问题一般都不是技术问题,多数是疏忽。。。。
发表于 2018-6-28 14:56:22 | 显示全部楼层
我想问下你那个跨域解决了,配置文件的cookie也支持跨域了吗,我登录的验证吗,还有配置里面的cookie量都不支持

本版积分规则