跨域请求在firefox,opera中保持在预检阶段,但在chrome中工作

时间:2014-03-03 09:59:35

标签: google-chrome firefox zend-framework ember.js cors

我有一个支持带有ZfrCors模块的Zend Framework 2的api服务器,以启用跨源资源共享。

服务器端zfrcors config ::

<?php

/**
 * This is the config file for ZfrCors. Just drop this file into your config/autoload folder (don't
 * forget to remove the .dist extension from the file), and configure it as you want
 */

return array(
    'zfr_cors' => array(
         /**
          * Set the list of allowed origins domain with protocol.
          */
        'allowed_origins' => array('http://client.server'),

         /**
          * Set the list of HTTP verbs.
          */
        'allowed_methods' => array('GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'),

         /**
          * Set the list of headers. This is returned in the preflight request to indicate
          * which HTTP headers can be used when making the actual request
          */
        'allowed_headers' => array('Authorization', 'Access-Control-Allow-Origin', 'content-Type', 'application/x-www-form-urlencoded', 'application/json', 'text/javascript', 'text/html'),

         /**
          * Set the max age of the preflight request in seconds. A non-zero max age means
          * that the preflight will be cached during this amount of time
          */
        'max_age' => 3600,

         /**
          * Set the list of exposed headers. This is a whitelist that authorize the browser
          * to access to some headers using the getResponseHeader() JavaScript method. Please
          * note that this feature is buggy and some browsers do not implement it correctly
          */
         // 'exposed_headers' => array(),

         /**
          * Standard CORS requests do not send or set any cookies by default. For this to work,
          * the client must set the XMLHttpRequest's "withCredentials" property to "true". For
          * this to work, you must set this option to true so that the server can serve
          * the proper response header.
          */
        'allowed_credentials' => true,
    ),
);

在客户端登录时(我的客户端应用程序是ember.js),它会向api.server域(localhost)发送请求。但是在预检请求后的Firefox中没有任何反应。它只给我200 OK状态消息并坐在那里。但是,如果我在Chrome中运行客户端应用程序,它会从预检阶段传递到实际的请求。

这是我的Firefox检查元素结果,同时将发布凭据发送到另一个域:

Access-Control-Allow-Cred...    true
Access-Control-Allow-Head...    Authorization, Access-Control-Allow-Origin, Content-Type, application/x-www-form-urlencoded
Access-Control-Allow-Meth...    GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Orig...    http://client.server
Access-Control-Max-Age  0
Connection  Keep-Alive
Content-Encoding    gzip
Content-Length  20
Content-Type    text/html
Date    Tue, 04 Mar 2014 08:38:29 GMT
Keep-Alive  timeout=5, max=100
Server  Apache/2.2.22 (Ubuntu)
Vary    Accept-Encoding
X-Powered-By    PHP/5.4.9-4ubuntu2.4

Request Headersview source
Accept  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Access-Control-Request-He...    content-type
Access-Control-Request-Me...    POST
Cache-Control   no-cache
Connection  keep-alive
DNT 1
Host    api.server
Origin  http://client.server
Pragma  no-cache
User-Agent  Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:27.0) Gecko/20100101 Firefox/27.0

在Chrome中执行相同的请求:

预检阶段:

Request URL:http://api.server/login
Request Method:OPTIONS
Status Code:200 OK

Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:api.server
Origin:http://client.server
Referer:http://client.server/signin
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36

Response Headersview source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Authorization, Access-Control-Allow-Origin, Content-Type, application/x-www-form-urlencoded
Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin:http://client.server
Access-Control-Max-Age:0
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:20
Content-Type:text/html
Date:Mon, 03 Mar 2014 07:18:41 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.2.22 (Ubuntu)
Vary:Accept-Encoding
X-Powered-By:PHP/5.4.9-4ubuntu2.4

实际的帖子请求标题:

Request URL:http://api.server/login
Request Method:POST
Status Code:200 OK

Request Headersview source
Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:55
Content-Type:application/json; charset=UTF-8
Host:54.254.23.183
Origin:http://client.server
Referer:http://client.server/signin
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36
Request Payloadview source
{identity:pbehera, password:123, remember:true}
identity: "pbehera"
password: "123"
remember: true

Response Headersview source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://client.server
Access-Control-Expose-Headers:
Connection:Keep-Alive
Content-Length:31
Content-Type:application/json; charset=utf-8
Date:Mon, 03 Mar 2014 07:18:42 GMT
Keep-Alive:timeout=5, max=99
Server:Apache/2.2.22 (Ubuntu)
Vary:Origin
X-Powered-By:PHP/5.4.9-4ubuntu2.4

我做错了什么?与Firefox一样的情况也是如此。

1 个答案:

答案 0 :(得分:1)

标题字段Access-Control-Allow-Origin:在Firefox和Chrome之间有所不同。此字段指定的URL必须与运行javascript的页面的域(主机+端口)匹配,因为您指定要发送凭据。出于某种原因,这可能不是Firefox请求的情况。