haproxy动态添加header add_header nginx_haproxy动态添加header


前段时间在公司基于 qiankun 推行微前端,由于主应用和子应用不同域,需要子应用 Nginx 服务器支持跨域。在推进的过程中,发现各组负责接入的前端同学在配置子应用的 add_header时,经常遇到配置 CORS 不生效的问题。


haproxy动态添加header add_header nginx_nginx css js无法访问_02


当然本篇文章的内容跟微前端没关系~

即使你在日常开发中没有接触过 Nginx,但作为前端工程师,网络请求和我们息息相关,各种头字段更是让人云里雾里的。熟悉 Nginx 及 add_header 指令可以帮助我们快速的搭建静态资源服务器,对各种header字段进行实验和验证。

先来看看官方介绍,我们把官方介绍分为三部分。


haproxy动态添加header add_header nginx_nginx css js无法访问_03

我们把官方描述分为三部分进行分析

第一部分

Adds the specified field to a response header provided that the response code equals 200, 201 (1.3.10), 204, 206, 301, 302, 303, 304, 307 (1.1.16, 1.0.13), or 308 (1.13.0). Parameter value can contain variables.

add_header 指令用于添加返回头字段,当且仅当状态码为图中列出的那些时有效。

我们来验证一下:


haproxy动态添加header add_header nginx_nginx css js无法访问_04

nginx 配置

在配置中,我给所有文件都加上了一个自定义header,名为test,值为111,现在通过8080端口访问如下:


haproxy动态添加header add_header nginx_js add方法_05


如我们所愿,返回头中带上了 test。

那我现在将状态码改为600,我们再来看看效果:


haproxy动态添加header add_header nginx_js add方法_06


果然跟文档一样,返回头没有带上 test,那我们如何使得test字段生效呢,官方介绍在第三部分中提到了解决方法。

第三部分

If the alwaysparameter is specified (1.7.5), the header field will be added regardless of the response code.

翻译过来就是,如果提供了第三个参数 always,那么无论状态码是多少,都会带上:我们加上试试看:


haproxy动态添加header add_header nginx_js add方法_07


haproxy动态添加header add_header nginx_js add方法_08


果然生效了,最后我们来看第二部分~

第二部分

介绍第二部分前,我们先来回顾一个常见的前端场景:

为了提升网站的二次打开速度以及减小服务器压力,我们需要通过将静态资源(css、js)设置为强缓存,不过需要将html文件设置为协商缓存,cache-control:no-cache,避免html也被缓存,导致用户不能及时更新最新的内容。

所以在 Nginx 中,需要对 html 文件做特殊处理,现在我们来操作下:


haproxy动态添加header add_header nginx_add remove server找不到_09


从图中可以看出,对于html文件,cache-controll 确实生效了,但是自定义headertest


haproxy动态添加header add_header nginx_nginx header参数丢失_10


js文件依旧保留了 test,这是什么原因呢?

那此时就需要提到官方介绍中的第二部分了:

There could be several add_headerdirectives. These directives are inherited from the previous level if and only if there are no add_headerdirectives defined on the current level.

简单明了翻译过来就是:

每一层都可以从上层继承 add_header,但是如果当前层添加了add_header,则不能继承。

这里的“层“是使什么呢?


haproxy动态添加header add_header nginx_nginx header参数丢失_11


  1. http 模块
  2. server 模块
  3. location 模块
  4. location中的 if 模块

所以在本例中当判断 html 文件时,使用到了 if 模块,并且在 if 模块中使用了 add_header,导致没有继承到最外层的 add_header test 111;

解决方法也比较简单,

  1. 把外层的add_header复制一份
  2. 当add_header指令用的很多时,可以抽离成.conf文件,通过include进行引入。

最后再介绍一种情况,就是 try_files 指令也是导致 add_header 失效,原理其实是一样的。


haproxy动态添加header add_header nginx_haproxy动态添加header_12


当当前 location 中找不到目标文件,会在内部重定向到 try_files 最后一个参数指定的 location,同时add_header也会失效,我们来看个例子:


haproxy动态添加header add_header nginx_js add方法_13


我们将css、js等文件放入到 fe-demo 文件夹下,index.html 放到 fe-demo 同级,当我们访问 /fe-demo 时,css、js 基于 $uri 是可以找到文件的,所以属于 location /fe-demo,add_header test22 生效。


haproxy动态添加header add_header nginx_nginx css js无法访问_14


而由于 index.html 没有在 /fe-demo 下,所以 tryfiles 会重新到最后一个参数,也就是会重定向到 location /,那么 add_header test


haproxy动态添加header add_header nginx_nginx header参数丢失_15



感谢阅读~有帮助请点个赞支持下