Access-Control-Allow-Origin не появляется в заголовках ответов от codeigniter

Мой файл 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

Оказывается, он работал для меня только тогда, когда я устанавливал заголовки через header() синтаксиса PHP header() вместо синтаксиса codeigniter $CI->output->set_header() . Печально.

Благодаря первому комментарию @Yan на вопрос по этой теме

Если вы внимательно присмотритесь, вы также заметите, что тип контента отличается: 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. Вызовите функцию _display () функции выходной библиотеки, чтобы сначала вывести правильные заголовки, а затем добавить ваш json-объект с эхом.

     $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)

после некоторого копания я обнаружил, что $ CI-> output-> set_header () работает – когда нет ошибки или исключения .

Когда есть ошибка или исключение, которое может уловить CI, классы вывода и представления полностью include(VIEWPATH.'errors/'.$template.'.php') а соответствующие страницы ошибок отображаются с include(VIEWPATH.'errors/'.$template.'.php') и заголовками, отправленными с помощью set_status_header($status_code) (находится в <CI System Dir>/core/Common.php )

см. <CI System Dir>/core/Exceptions.php

вот пример:

  /** * 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; } 

это раздражает тем, что делает DRY менее прямым. чтобы обойти это, я предлагаю вам создать вспомогательную функцию, например (непроверенную):

 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: CCC-Cocaine') : @header('X-Powered-By: Errors',true); } return true; } 

используйте эту функцию на разных страницах ошибок в <CI Views>/errors/error_*.php а также в ваших контроллерах.

Что для меня работало:

 $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();