map 指令是由 ngx_http_map_module 模块提供的,默认情况下安装 nginx 都会安装该模块。
map 的主要作用是创建自定义变量,通过使用 nginx 的内置变量,去匹配某些特定规则,如果匹配成功则设置某个值给自定义变量。 而这个自定义变量又可以作于他用。
map $args $foo {
default 0;
debug 1;
}
$args 是nginx内置变量,就是获取的请求 url 的参数。 如果 $args 匹配到 debug 那么 $foo 的值会被设为 1 ,如果 $args 一个都匹配不到 $foo 就是default 定义的值,在这里就是 0
map $var1 $var2 {...}
1、default : 指定源变量匹配不到任何表达式时将使用的默认值。当没有设置 default,将会用一个空的字符串作为默认的结果。
2、hostnames : 允许用前缀或者后缀掩码指定域名作为源变量值。这个参数必须写在值映射列表的最前面。
3、include : 包含一个或多个含有映射值的文件。
map 的 $var1 为源变量,通常可以是 nginx 的内置变量,$var2 是自定义变量。 $var2 的值取决于 $var1 在对应表达式的匹配情况。 如果一个都匹配不到则 $var2 就是 default 对应的值。
map $http_user_agent $agent {
default "";
~curl curl;
~*apachebench" ab;
}
map $uri $value {
/abc /index.php;
~^/teacher/(?.*)$ /boy/;
~/fz(/.*) /index.php?fz=1;
}
==注意:不能在map块里面引用命名捕获或位置捕获变量。如~^/qupeicom/(.*) /peiyin/$1; 这样会报错nginx: [emerg] unknown variable==
==注意二:如果源变量值包含特殊字符如‘~’,则要以‘\’来转义。==
map $http_referer $value {
Mozilla 111;
\~Mozilla 222;
}
map $http_referer $value {
Mozilla 'chrom';
\~safity $http_user_agent;
# 这些配置可以写在 http{} 或者 server{} 都是支持的。
add_header Access-Control-Allow-Origin "http://www.tutu.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;
#!/bin/bash
# 上面的配置只允许 http://www.tutu.com 跨域访问,如果要支持所有域名都可以跨域调用该站。 把上面一行改成这样,不过不推荐这样做,因为不安全
add_header Access-Control-Allow-Origin "*";
map $http_origin $corsHost {
default 0;
"~http://www.haibakeji.com" http://www.haibakeji.com;
"~http://m.haibakeji.com" http://m.haibakeji.com;
"~http://wap.haibakeji.com" http://wap.haibakeji.com;
}
server
{
listen 80;
server_name www.haibakeji.com;
root /nginx;
location /
{
add_header Access-Control-Allow-Origin $corsHost;
}
}
使用源变量(通常是 nginx 内置变量)匹配一些规则,创建自定义变量,然后在页面输出. 这通常在调试的时候非常有用
http {
map $uri $match {
~^/hello/(.*) http://www.hello.com/;
}
server {
listen 8080;
server_name test.hello.com;
location /hello {
default_type text/plain;
echo uri: $uri;
echo match: $match;
echo capture: $1;
echo new: $match$1;
}
大家可能会有一个问题,map 既然只能用在 http 段,这是全局的啊。 这个设置会让访问所有虚拟主机的请求都要匹配并设置一遍变量的值,然而事实并非如此,对于没有用到相关变量的请求来说,并不会执行 map 操作。 就没有性能上的损失。
如果匹配到多个特定的变量,如掩码和正则同时匹配,那么会按照下面的顺序进行选择:
- 没有掩码的字符串
- 最长的带前缀的字符串,例如: “*.example.com”
- 最长的带后缀的字符串,例如:“mail.*”
- 按顺序第一个先匹配的正则表达式 (在配置文件中体现的顺序)
- 默认值
- 语法: map_hash_bucket_size size;
- 默认值: map_hash_bucket_size 32|64|128;
- 配置段: http
指定一个映射表中的变量在哈希表中的最大值,这个值取决于处理器的缓存。
- map_hash_max_size
- 语法: map_hash_max_size size;
- 默认值: map_hash_max_size 2048;
- 配置段: http
- 设置映射表对应的哈希表的最大值。