AngularJS,PHP Restful Cors 问题

Posted

技术标签:

【中文标题】AngularJS,PHP Restful Cors 问题【英文标题】:AngularJS, PHP Restful Cors issue 【发布时间】:2015-02-23 14:08:16 【问题描述】:

我在尝试对我的 rest php 服务器进行 $http 调用时遇到问题。 我正在做从客户端到后端的跨域调用。

在我的 Angular 应用程序中,这是 $http 服务的配置方式:

.config(['$httpProvider', function($httpProvider) 
    $httpProvider.interceptors.push('httpResponseInterceptor');
    $httpProvider.interceptors.push('httpTimeStampMarker');
    $httpProvider.defaults.useXDomain = true;
    $httpProvider.defaults.headers.post['Access-Control-Allow-Origin'] = '*';
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
    delete $httpProvider.defaults.headers.common['Content-Type, X-Requested-With'];
])

这是实际 $http.post() 的配置方式:

    // Set the headers
    var headers = 
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT',
        'Content-Type': 'application/x-www-form-urlencoded',
        'Accept': '*'
    ;

    return $http(
            method: "POST",
            url: base_url,
            data: $.param(args),
            headers: headers
        )
        .success(function(data, status) 

        )
        .error(function(data, status) 

        );

这是服务器的.htaccess:

# Cors
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Methods"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

预检请求正常:

**Request headers:**
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:access-control-allow-origin, accept, access-control-allow-methods, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:***
Origin:***
Referer:***
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/39.0.2171.95 Safari/537.36

**Response headers**
Access-Control-Allow-Headers:Origin, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Methods
Access-Control-Allow-Methods:PUT, GET, POST, DELETE, OPTIONS
Access-Control-Allow-Origin:*
Allow:OPTIONS,GET,HEAD,POST
Connection:Keep-Alive
Content-Length:0
Content-Type:httpd/unix-directory
Date:Fri, 26 Dec 2014 07:12:24 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.4.9 (Unix) PHP/5.6.2

然而实际发布请求失败:

XMLHttpRequest cannot load http://***/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '***' is therefore not allowed access. The response had HTTP status code 404.

这些是请求和响应标头:

**Request headers**
    Accept:*
    Accept-Encoding:gzip, deflate
    Accept-Language:en-US,en;q=0.8
    Access-Control-Allow-Methods:POST, GET, OPTIONS, PUT
    Access-Control-Allow-Origin:*
    Connection:keep-alive
    Content-Length:130
    Content-Type:application/x-www-form-urlencoded
    Host:***
    Origin:http://***
    Referer:***
    User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36


**Response headers**
Connection:Keep-Alive
Content-Length:198
Content-Type:text/html; charset=iso-8859-1
Date:Fri, 26 Dec 2014 07:12:24 GMT
Keep-Alive:timeout=5, max=99
Server:Apache/2.4.9 (Unix) PHP/5.6.2

我显然在发布请求的响应中缺少一些标头。

但是,它失败的问题在预检请求中确实有效。我尝试在其余服务器的 index.php 中添加一些标头,但是请求没有到达那里并且更早卡住了(我猜是什么时候加载 .htaccess 的)。

我在这里错过了什么?

【问题讨论】:

【参考方案1】:

尝试在您的 .htaccess 中使用 set 而不是 add

Header set Access-Control-Allow-Origin "*"

查看更多here

【讨论】:

谢谢,我试过了,但没有成功。将添加更改为设置,重新启动 apache,但问题仍然存在。预检请求正常,发布请求不正常。【参考方案2】:

几个小时后我终于找到了。

我的 .htaccess:

# Cors
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Access-Control-Allow-Origin"
Header always set Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

@Alexey Rodin 给出的提示几乎是正确的。与其将“add”改为“set”,不如将其设置为“always set”。

这个site帮助了我:

关于 AngularJS,我可以确认 CORS 工作不需要其他设置。 因此 Angular 的 $http 不需要更改标题左右,默认设置应该适用于上述 .htaccess 条目。

【讨论】:

以上是关于AngularJS,PHP Restful Cors 问题的主要内容,如果未能解决你的问题,请参考以下文章

AngularJs调用Restful实现CRUD - AngularJs

AngularJS+Node的RESTful之基本实现

Spring Security 401 - 使用 / Angularjs 调用 restful 服务

AngularJS RESTful 参数

如何使用 angularjs 在 RESTful 请求中执行授权?

黄聪:AngularJS中的$resource使用与Restful资源交互(转)