3

我的 Codeigniter 文件说

$CI->output->set_header("Access-Control-Allow-Origin: *");
$CI->output->set_header("Access-Control-Expose-Headers: Access-Control-Allow-Origin");
$CI->output->set_status_header(200);
$CI->output->set_content_type('application/json');
echo json_encode(array("city" => "dhaka"));

但我得到的http响应是:

Request URL:http://localhost/index.php/location/city
Request Method:POST
Status Code:200 OK

Connection:Keep-Alive
Content-Length:16
Content-Type:text/html
Date:Sun, 22 Jul 2012 10:27:32 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
X-Powered-By:PHP/5.3.6

即使Access-Control-Allow-Origin包含Access-Control-Expose-Headers: Access-Control-Allow-Origin. 我有关此标头的信息来源来自Mozilla 开发者网站

4

4 回答 4

5

事实证明,只有当我通过 PHP 语法header()而不是 codeigniter 语法设置标头时,它才对我有用$CI->output->set_header()。这很可悲。

感谢@Yan在本主题问题上的第一条评论

于 2012-11-24T02:03:55.837 回答
3

如果您仔细观察,您还会注意到内容类型不同:它是text/html,而您正在请求application/json。发生这种情况是因为当您正确准备标题时,您从未真正输出它们。据我所知,您至少可以通过两种方式做到这一点:

  1. 使用输出库的 set_output 函数一次输出所有内容。

    $json = json_encode(array("city" => "dhaka"));
    
    $this->output->set_header("Access-Control-Allow-Origin: *");
    $this->output->set_header("Access-Control-Expose-Headers: Access-Control-Allow-Origin");
    $this->output->set_status_header(200);
    $this->output->set_content_type('application/json');
    
    $this->output->set_output($json);
    
  2. 调用 output-library 的 _display() 函数,首先输出正确的标头,然后将您的 json 对象附加到 echo。

    $this->output->set_header("Access-Control-Allow-Origin: *");
    $this->output->set_header("Access-Control-Expose-Headers: Access-Control-Allow-Origin");
    $this->output->set_status_header(200);
    $this->output->set_content_type('application/json');
    $this->output->_display();
    
    echo json_encode(array("city" => "dhaka"));
    

    此函数将最终的输出数据连同任何服务器标头和配置文件数据一起发送到浏览器。(来自 CI/system/core/Output.php 第 316 行)

于 2012-11-21T20:47:18.730 回答
0

after some digging around, i found that $CI->output->set_header() does work - when there isn't an error or exception.

When there is an error or exception that CI can catch, the output & view classes are bypassed completely and the appropriate error pages are rendered with include(VIEWPATH.'errors/'.$template.'.php') and headers sent with set_status_header($status_code) (located at <CI System Dir>/core/Common.php)

see <CI System Dir>/core/Exceptions.php

here's a sample:

    /**
     * General Error Page
     *
     * Takes an error message as input (either as a string or an array)
     * and displays it using the specified template.
     *
     * @param   string      $heading    Page heading
     * @param   string|string[] $message    Error message
     * @param   string      $template   Template name
     * @param   int     $status_code    (default: 500)
     *
     * @return  string  Error page output
     */
    public function show_error($heading, $message, $template = 'error_general', $status_code = 500)
    {
        set_status_header($status_code);

        $message = '<p>'.implode('</p><p>', is_array($message) ? $message : array($message)).'</p>';

        if (ob_get_level() > $this->ob_level + 1)
        {
            ob_end_flush();
        }
        ob_start();
        include(VIEWPATH.'errors/'.$template.'.php');
        $buffer = ob_get_contents();
        ob_end_clean();
        return $buffer;
    }

it's annoying in that it makes DRY less straight forward. to work around it, i suggest you create a helper function, for example (untested):

function my_generate_headers($headers=array(),$useOutputClass=true)
{
    if(is_array($headers) && count($headers)<1) return false;

    foreach($headers AS $eHeader)
    {
        ($useOutputClass) ? 
                    get_instance()->output->set_header('X-Powered-By: C-C-C-Cocaine') : 
                    @header('X-Powered-By: Errors',true);
    }

    return true;
}

use that function in your different error pages at <CI Views>/errors/error_*.php as well as in your controllers.

于 2013-02-14T09:52:45.020 回答
0

对我有用的是:

$this->output
  ->set_header('Access-Control-Allow-Origin: http://localhost:4567')
  ->set_header('Content-type: application/json')
  ->set_status_header(200)
  ->set_output( json_encode($to_encode) )
  ->_display();
于 2016-07-26T18:18:15.177 回答