Управление доступом-Разрешить-Происхождение не отображается в заголовках ответов от 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
4 answers
Оказывается, это сработало для меня только тогда, когда я установил заголовки с помощью синтаксиса PHP header()
вместо синтаксиса codeigniter $CI->output->set_header()
. Это печально.
Благодаря первому комментарию @Yan на Вопрос из этой темы
Если вы посмотрите внимательно, вы также можете заметить, что тип контента отличается: это text/html
, в то время как вы запрашиваете application/json
. Это происходит потому, что, хотя вы правильно готовите заголовки, вы никогда не выводите их на самом деле. Насколько я знаю, вы можете сделать это по крайней мере 2 способами:
-
Используйте функцию 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);
-
Вызовите функцию _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)
Немного покопавшись, я обнаружил, что $CI->вывод->set_header() работает - , когда нет ошибки или исключения.
При возникновении ошибки или исключения, которые может перехватить CI, классы вывода и представления полностью обходятся, а соответствующие страницы ошибок отображаются с помощью 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: C-C-C-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();