在 codeigniter 中应优先使用 $this->output->set_header() 设置自定义 http 头,且必须在输出开始前调用(如控制器末尾、load->view() 前或 _output() 方法中);rest 接口需配合 set_content_type() 避免 mime 冲突;原生 header() 易被框架覆盖,cors 头须在基控制器或 _remap() 中统一处理预检请求。

如何在 CodeIgniter 响应中添加自定义 HTTP 头
直接用 $this->output->set_header(),但要注意它只在输出未开始前生效;一旦 echo、var_dump() 或视图已输出内容,再调用就无效。
- 推荐在控制器方法末尾、
$this->load->view()之前设置,或在_output()方法里统一处理 - 若使用 REST 接口(比如返回 JSON),建议搭配
$this->output->set_content_type('application/json')一起用,避免 MIME 类型和头信息冲突 - 注意:CodeIgniter 3 默认不自动发送
Content-Type,如果没显式设置,浏览器可能按text/html解析 JSON 响应
为什么 header() 函数有时不生效
因为 CodeIgniter 的输出类会接管响应流程,直接调用 PHP 原生 header() 可能被后续的 $this->output 操作覆盖,尤其在启用缓存或使用 enable_profiler 时更明显。
- 优先走框架接口:用
$this->output->set_header('X-App-Version: 2.1.0')而非header('X-App-Version: 2.1.0') - 若必须用原生
header(),确保它出现在任何输出之前,且关闭输出缓冲干扰(检查是否误启了ob_start()) - 调试时可查
headers_sent()返回值,确认头是否已被发送
跨域(CORS)头设置的常见陷阱
Access-Control-Allow-Origin 等 CORS 头不能只写在某个方法里——前端发预检请求(OPTIONS)时,控制器可能根本没走到你写的那行 set_header()。
- 在基控制器(如
MY_Controller)的构造函数中统一设置,或重写_remap()方法提前拦截 - 对 OPTIONS 请求,需单独响应 200 并带上完整 CORS 头,否则浏览器直接报错
Response to preflight request doesn't pass access control check - 避免通配符
*和Credentials: true同时使用;真要带 cookie,得写具体域名,比如https://example.com
JSON 响应中添加头信息的正确姿势
很多人想给 json_encode() 输出加头,却忘了 CodeIgniter 的 json() 辅助方法(CI3.1+)或手动 set_content_type() 才是关键路径。
- CI3 推荐写法:
$this->output ->set_content_type('application/json') ->set_header('X-Data-Timestamp: ' . time()) ->set_output(json_encode($data)); - 别在
json_encode()后再 echo —— 这会让输出类无法控制头信息 - 如果用了
$this->output->cache(60),自定义头仍有效,但注意缓存的是整个响应(含头),所以动态头(如时间戳)不适合缓存









