- 1) map 指令是由 'ngx_http_map_module 模块'提供的,默认情况下安装 nginx 都会'安装'该模块.
-
- 2) map 的主要作用是'创建自定义变量',通过使用 nginx 的'内置'变量,去'匹配'某些特定规则;如果匹配成功则设置某个值给自定义变量,而这个'自定义变量'又可以'用作他用'。
- 强调:和'内置变量'才能玩出'花样'
-
- 说明:'string'一般我们会用'nginx的内置变量'来代替,不会直接写'裸值',便于'动态'
-
- 补充:已知'set、map、正则命名补获(?<name>.*)'三种方式来'设置变量'
1)正则扩展
2)正则注意事项
4)补充
① 简单案例
- map $args $foo {
- default 0;
- debug 1;
- }
-
- 变量解读:$args 是nginx'内置[inner]'变量,$foo是我们自定义的'普通[common]'变量
-
- 附加:$args 这个变量等于'请求行中(GET请求)的参数',例如foo=123&bar=wzj;
-
- 效果:如果 $args '匹配到 debug' 那么 $foo 的值会'被设为 1 ';如果 $args 一个都'匹配不到' $foo 就是'default 定义的值',在这里就是 0
-
- 大白话:类似于一个'if/else'判断,设置'变量值'
② 案例一:nginx开启websocket代理功能
- http {
- ...
- # 是否是'websocket'
- map $http_upgrade $connection_upgrade {
- default upgrade;
- '' close;
- }
-
- location /v1/kind {
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection $connection_upgrade;
- # proxy_set_header Connection "upgrade"; -->对比二者的区别?
- ...
- }
- }
websocket协议为什么HTTP Upgrade的时候需要Connection: upgrade ?
WebSocket为什么需要Connection和Upgrade两个header?
③ 案例二:后端代理切不同的版本、或者兰绿发布
- upstream upstream_k8s {
- server ip:port;
- ...
- }
-
- upstream upstream_default {
- server ip:port
- }
-
- # zone是存储区域
- limit_req_zone $client_real_ip zone=A:100m rate=1000r/s
- limit_conn_zone $client_real_ip zone=B:100m;
-
- # 变量必须是nginx的内置变量吗? -->'非必须'
-
- map $COOKIE_k8s_flag $k8s {
- # 等待匹配的字符串可以不加引号
- k8s1 upstream_k8s;
- # 说明:upstream_default和upstream_k8s与前面的映射
- deafult upstream_default;
- }
-
-
- location /k8s {
- limit_req zone=A burst=10000 nodelay;
- limit_conn B 1000;
- # 注意引入方式
- proxy_pass https://${k8s};
- ...
- }
④ 案例三:跨域名访问
- # 这些配置可以写在 http{} 或者 server{} 都是'支持'的
- add_header Access-Control-Allow-Origin "http://www.wzj.com";
- add_header Access-Control-Allow-Methods "POST, GET, PUT, OPTIONS, DELETE";
- add_header Access-Control-Max-Age "3600";
- add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
-
- 1) 上面的配置'只允许' http://www.wzj.com 跨域访问
-
- 2) 如果要支持'所有域名'都可以跨域调用该站, 不过'不推荐'这样做,因为'不安全'
-
- add_header Access-Control-Allow-Origin "*";
-
- ++++++++++++++"不想允许所有,但是又需要允许多个域名,那么就需要用到 map"++++++++++++++
-
- 需求: 使用 map 来实现允许'多个域名跨域'访问的问题
-
- map $http_origin $corsHost {
- default 0;
- "~http://www.wzj.com" http://www.wzj.com;
- "~http://m.haibakeji.com" http://harbor.wzj.com;
- "~http://nginx.wzj.com" http://nginx.wzj.com;
- }
-
- server{
- listen 80;
- server_name www.wzj.com;
- root /nginx;
- location /
- {
- add_header Access-Control-Allow-Origin $corsHost;
- ...
- }
- }
⑤ map相关调试
- 需求:使用源变量'通常是 nginx 内置变量'匹配一些规则,创建自定义变量,然后在页面输出. 这通常在'调试'的时候非常有用
-
- 复制代码
- http {
- map $uri $match {
- # 说明:default可以'省略'
- ~^/www/(.*) http://www.wzj.com/;
- }
- server {
- listen 8080;
- server_name harbor.wzj.com;
-
- location /www {
- default_type text/plain;
- echo uri: $uri;
- echo match: $match;
- echo capture: $1;
- echo new: $match$1;
- }
⑥ map性能问题
⑦ 匹配优先级
</article>