http请求header及nginx转发问题

5,145 阅读3分钟

前言

       最近在项目http请求中使用header频次颇多,于是总结一下header的用法及遇到的一些坑。

常见请求体公共header

        常见的一些请求方发送的公共header如下所示:

名称 示例 说明
Host www.xxx.com 本次http请求的host地址
Content-Type application/json post、put请求body数据格式
Accept-Language zh-CN 接收数据的内容语言列表
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/70.0 请求发起方的用户信息 浏览器或设备版本信息,可以通过这个取出设备及版本信息,做版本兼容或设备区分
Referer www.baidu.com/s?wd=header 多用于web网站中表示请求发起之前的页面地址,即引导至这个页面的上一个页面地址。可以基于这个做百度、谷歌等搜索引擎到当前网页的关键词分析。
cookie sensorsdata2015jssdkcross=%7B%2 这个域名下之前存在的cookie数据
Connection keep-alive 是否需要持久化链接
Date Dec, 26 Dec 2019 17:30:00 GMT 请求发起时间点

       除了上面的请求体中的公共header,我们还可以定义一些其他header:如token、移动端的唯一设备id、一些自己业务的基础属性如用户id、城市id等等。

  1. 基于此可以根据设备、用户、点击链路做出用户行为分析,优化当前的产品,甚至是用在广告的个性化推荐上;
  2. 服务端可以基于这些基本信息对每个行为做日志记录;

nginx、apache服务器对header下划线过滤

问题出现及定位

       上面说的一些header的用法及常见的公共header,但在上周的业务使用中却出现了一些问题,客户端通过header传递了一个key为a_b的header,但是我们服务端却在getHeader中拿到的是null,其他的header正常,在检查了拼写问题及使用Charles工具抓包后,确认客户端传递了这个a_b的header,但没有传递到服务端,而且我们的一些过滤器也没有针对header做特殊处理。

       因此想到了是不是代理服务器的问题,我们每个服务端都会使用nginx做一层代理转发,而查询相关资料后发现nginx服务器默认会对http请求中带下划线的header做过滤丢失不会透传,需要在配置中打开这个选项即可,如下:

nginx.conf
http
	{
        underscores_in_headers on;
    }

原因

        为什么会使nginx和apache服务器对名称中带下划线header不做转发呢,查阅相关资料后发现是CGI(公共网关接口Common Gateway Interface,CGI是Web 服务器运行时外部程序的规范)的历史遗留问题如下,大概意思就是 下划线和中划线都为会被映射为 CGI 系统变量中名中的下划线,这样容易引起混淆。

If you do not explicitly set underscores_in_headers on ;, nginx will silently drop HTTP headers with underscores (which are perfectly valid according to the HTTP standard). This is done in order to prevent ambiguities when mapping headers to CGI variables, as both dashes and underscores are mapped to underscores during that process.

        因此我们在以后的header使用中,需要客户端和浏览器制定更规范的header名称,尽量避免使用带下划线的内容。

结语

        之前开发周期比较紧,除了鉴权及ua之外很少关注header中的内容,这次整理之后发现我们当前cs交互中有很多冗余的业务数据既在header中传递又在接口中传递,能够使用它做一些更多的事情。

参考资料:www.nginx.com/resources/w… www.jianshu.com/p/2320f1ece…