nginx配置

2020-03-04

#user  nobody;
worker_processes  auto;

error_log  logs/error.log warn;

pid        logs/nginx.pid;

events {
    # windows下不能设置
    use epoll;
    worker_connections  1024;
}
master_process on;
daemon on;
http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format main '$remote_addr - $remote_user [$time_local] "$host" "$request" '
    #                '"$request_uri"'$status $request_time "$http_referer" '
    #                '"$http_user_agent" "$http_x_forwarded_for"';

    sendfile        on;
    tcp_nopush     on;
    tcp_nodelay on;

    keepalive_timeout  65;

    server_names_hash_bucket_size 512;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    client_max_body_size 50m;

    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300;
    fastcgi_buffer_size 64k;
    fastcgi_buffers 4 64k;
    fastcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 256k;
    fastcgi_intercept_errors on;

    gzip on;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 2;
    gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
    gzip_vary on;
    gzip_proxied   expired no-cache no-store private auth;
    gzip_disable   "MSIE [1-6]\.";

    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;

    server_tokens off;
    access_log off;
    
    #是否在error_log中记录不存在的错误
    log_not_found on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

    include vhost/*.conf;
}

nginx配置内容

    1、配置支持变量,(内置变量和自定义变量)引用变量: $变量名

main block 主配置段,全局配置,对http,mail,stream都有效

1、user nginx; 指定运行nginx的用户 只能放在主配置段
2、pid=path; nginx的pid文件的位置
3、load_module; 加载模块
4、worker_processes number|auto; worker进程数量,auto表示根据cpu自适应 number是自定义的数字 (需要重启服务才能加载配置)建议设置为 cpu的内核数或内核数的倍数
5、worker_cpu_affinity cpumask;  绑定cpu与worker进程 cpumask:0001:0号cpu 0010:1号cpu 1000:8号cpu
		绑定配置:worker_cpu_affinity 0010 0100;两个worker进程分别绑定到第二个,第三个cpu上
6、worker_priority number; work进程优先级(-20到20)
7、worker_rlimit_nofile number; 每个worker进程所能打开的文件数量(每个worker能处理的请求数)
8、events {
	 worker_connections number; 每个worker进程的最大并发数
         1.connections不是随便设置的,而是与两个指标有重要关联,一是内存,二是操作系统级别的“进程最大可打开文件数”。cat /proc/sys/fs/file-max 查看linux的最大连接数
         2.内存:每个连接数分别对应一个read_event、一个write_event事件,一个连接数大概占用232字节,2个事件总占用96字节,那么一个连接总共占用328字节,通过数学公式可以算出100000个连接数大概会占用 31M = 100000 * 328 / 1024 / 1024,当然这只是nginx启动时,connections连接数所占用的nginx。
         3.进程最大可打开文件数:进程最大可打开文件数受限于操作系统,可通过 ulimit -n 命令查询,以前是1024,现在是65535,

	 use method; 指明并发连接请求的处理方法,默认自动选择最优方法;method默认为epoll;windows下不能配置为epoll;
}
9、daemon on|off;  nginx是否有守护进程运行
10、master_process on|off; 是否以master worker模式运行 off时将不会有worker进程,都将有master处理
11、error_log file [level]; 错误日志的位置  (注:错误日志文件及其级别处于调试需要,可设定为debug,但debug仅在编译时使用了"--with-debug"选项时才有效)
 	stderr:发送到标准错误
 	syslog:server-address[,parameter=values] 发送日志到远程服务器上,
 	memory:size 内存 
 	level(debug|info|notice|warn|crit|alter|emerg)
12、gzip on|off; gzip压缩 http、server、location都可以配置
	1、gzip_comp_level level; 压缩比由低到高 1到9
	2、gzip_disable regx; 匹配到客户端浏览器不执行压缩
	3、gzip_min_length length; 启用压缩功能的响应报文大小阈值
	4、gzip_http_version 1.0|1.1; 设定启用压缩功能, 协议的最小版本,默认1.1
	5、gzip_buffers number size; 支持实现压缩功能时缓冲区数量及每个缓存区的大小 默认32 4K或 16 8K
	6、gzip_types mime-type; 指明仅对哪些类型的资源执行压缩操作,即压缩过滤器,默认包含有text/html 不用显示指定,否则报错
	7、gzip_vary on|off; 如果启用压缩,是否在响应报文首部插入 'Vary:Accept-Encoding'
	8、gzip_proxied off|expired |no-cache|no-store|private|no_last_modified|no_etag|auth|any...; nginx充当代理服务器时,对于后端服务器的响应报文,在何种条件下启用压缩功能,off不启用压缩 expired,no-cache,no-store,private:对后端服务器的响应报文首部Cache-Control值任何一个,启用压缩功能

http协议的配置段

server { #每个server用于定义一个虚拟主机
	1、listen  port|ip:port|[::]:80(ipv6的地址) [default_server|ssl|backlog|rcvbuf|sndbuf]; 监听端口
		default_server 设定默认连接虚拟主机
		ssl 限制只能够通过ssl连接提供服务
		backlog=number 超过并发连接数后,新请求进入后援队列的长度 number自定义
		rcvbuf=size 接收缓冲区大小 size自定义
		sndbuf=size 发送缓冲区大小 size自定义
	2、server_name www.a.com; 指令指向不同的主机名 可以指定IP 表示使用IP访问时将访问当前的server 例:server_name www.a.com 192.168.1.1
		支持*通配符 例:*.a.com
		支持~起始的正则表达式 例:~^www\d+\.a\.com$
		匹配优先级:
	    	1、字符串精确匹配
			2、左侧*通配符
			3、右侧*通配符
			4、正则表达式
			5、default_server
	3、root  网站根目录 在location中配置时:解释规则-》最后访问的是:root路径+location路径
	4、tcp_nodelay on|off; 在keepalive模式下的连接是否启用TCP_NODELAY选项,当为off时,延迟发送,合并多个请求后在发送,默认为on,不延迟发送
	5、sendfile on|off; 是否启用sendfile功能,在内核中封装报文直接发送,默认为off
	6、server_tokens on|off|build|string; 是否响应报文的server首部显示nginx版本 http/server/loaction都可以设置,商业版可以修改string
	7、location [=|~|~*|^~] url;
			= 精确匹配
			^~ 对url最左边部分做匹配检查,不区分字符大小写
			~  对url做正则表达式模式匹配,区分字符大小写
			~* 对url做正则表达式模式匹配,不区分字符大小写
			不带符号 匹配起始于此url的所有url
			匹配优先级:=,^~,~|~*,不带符号
	8、alias path; 路径别名,文档映射的另一种方式,仅能使用在location中 解释规则-》alias路径替换location路径
	9、index file; 指定默认网页文件
	10、error_page_code; 定义错误页,以指定的响应状态;可用位置:http,server,location,if in location
		error_page_code 404 =200 /404.html; 返回的状态码是200,但是进入的还是404页面,防止360等浏览器劫持错误页面
		location /404.html {
			root /error/;
		}
	11、try_files file uri [=code] 按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹)
        如果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。
        查找路径是按照给定的root或alias为根路径来查找的
        只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部uri的指向。
        最后一个参数是回退uri且必须存在,否则会出现内部500错误 (指定一个地址,如果找不到这个地址,返回一个默认的信息,可以返回多个文件(会依次查找,最后一个文件必须存在),可以指定返回的code)
	    示例:
			location /images/ {
				try_files $uri /images/default.gif;
			}
			location / {
				try_files $uri $uri/index.html $uri.html =404;	
			}
	12、keepalive_timeout timeout [header_timeout] 设定保持连接超时时长,0表示禁止长连接,默认为75s 根据场景需求修改
	13、keepalive_requests number 在一次长连接上所允许请求的资源的最大数量 默认为100 超过就会断开长连接
	14、keepalive_disabled none|brower 对哪种浏览器禁用长连接
	15、send_timeout time 向客户端发送响应报文的超时时长,此处是指两次写操作之间的间隔时长,而非整个响应过程的传输时长
	16、client_body_buffer_size size 用于接收每个客户端请求报文的body部分的缓冲区大小,默认为16K;超出此大小时,其将被暂存到磁盘上的有下面client_body_temp_path指令所定义的位置
	17、client_body_temp_path path [level1] [level2] [level3] 设定存储客户端请求报文的body部分的临时存储路径及子目录机构和数量目录名为16进制的数字;
		client_body_temp_path /var/tmp/client_body 1 2 2
		1 1级目录占1为16进制,即2^4=16个目录 0-f
		2 2级目录占2为16进制,即2^8=256个目录 00-ff
		2 3级目录占2为16进制,即2^8=256个目录 00-ff
	18、limit_rate rate(字节为单位) 限制响应给客户端的传输速率,单位是bytes/second 默认为0 无限制
	19、limit_except method ... 仅用于location 限制客户端使用除了指定的请求之外的其他方法
		示例:limit_except GET {
			allow 192.168.1.0/24; 除了get和head之外的方法只有192.168.1.0/24网段可以访问
			deny all; 除了get和head之外的方法所有人都不可以访问
		}
	20、aio on|off|threads[=pool] 是否启用 aio功能 (异步io)
	21、directio size|off 当文件大于等于给定大小时,例如directio 4M 同步(直接)写磁盘,而非写缓存
	22、open_file_cache off;
		open_file_cache max=N [inactice=time];
		nginx可以缓存一下三种信息:
			1、文件元数据:文件的描述符,文件大小和最近一次的修改时间
			2、打开的目录结构
			3、没有找到的或者没有权限访问的文件的相关信息
		max=N 可缓存的缓存项上限;达到上限后会使用LRU算法实现管理
		inactice=time 缓存项的非活动时长,在此处指定的时长内未被命中的或命中的次数少于 
        open_file_cache_min_user指令所指定的次数的缓存项即为非活动项,将被删除
	23、open_file_cache_errors on|off 是否缓存查找时发生错误的文件一类的信息 默认值为off
	24、open_file_cache_min_user number open_file_cache指令的inactive参数指定的时长内,至少被命中此处指定的次数方可被归类为活动项 默认值为1
	25、open_file_cache_valid time 缓存项有效性的检查频率 默认值为60s
		访问模块(ngx_http_access_module):
		实现基于ip的访问限制功能 自上而下检查,一旦匹配就会生效
		1、deny address | CIDR |unix:|all; 限制访问
		2、allow address | CIDR |unix:|all; 允许访问
}

实现基于用户的访问控制,使用basic机制进行用户认证

ngx_http_auth_basic_module模块 # http,server,location都可以配置
1、auth_basic string|off;  
2、auth_basic_user_file file;
   示例:
		location /admin/ {
			auth_basic "Admin Area";
			auth_basic_user_file /etc/nginx/.ngxpassword;
		}
用户口令文件:
	1、明文文本:格式name:password:comment
	2、加密文本:由htpassword命令实现 httpd-tools提供

用于输出nginx的基本状态信息:ngx_http_stub_status_module

location /status/ {
	stub_status;
	allow 127.0.0.1;
}

ngx_http_log_module (日志)

1、log_format name string 只能在http中定义
2、access_log path [format(log_format的name) [buffer=size] [gzip[=level]] [flush=time] [if=condtion]] 在http、server、location都可以定义;访问日志路径,格式及相关的缓冲的配置
3、open_log_file_cache max=N [inactice=time] [min_user=N] [valid=time]
	缓存各日志文件相关的元数据信息
	max:缓存的最大文件描述符数量
	min_user:在inactice指定的时长访问大于等于此值方可被当做活动项,
	inactive:非活动时长
	valid:验证缓存中各缓存项是否为活动项的时间间隔

访问控制:

1、限制带宽资源,访问连接数限制
	limit_coon_zone $binary_remote_addr zone=addr:10m; #在location中设置 //限制并发连接数
	limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; //限制请求次数 设置的值是每秒1次
	location /download/ {
		limit_coon addr 1; //并发数为1
		limit_req zone=one burst=5; //每秒请求次数1次,超过1个请求 5个放到队列中,超过的拒绝访问
		limit_rate 50k; //限制速率
		set $limit_rate 50k; //通过内置变量设置 限制速率
	}
2、获取客户端地址
	在server中配置:
		set_real_ip_from 172.25.0.1; //真实服务器的上级代理的ip或ip段
		real_ip_header X-Forwarded-For; //从哪个header头解析需要的地址
		real_ip_recursive on; // 递归去除虚假ip
3、图片压缩
	load_module ngx_http_image_filter_module.so;(linux需要安装时添加这个模块的配置,配置时需要引入该模块,需要写路径,从nginx根目录开始算起)
	location / {
		image_filter resize 150 150;
	}
4、ssl加密
	添加ssl模块 --with_http_ssl_module 编译时可能报错,需要安装openssl-devel
	配置server配置段
	server {
		listen 443 ssl;
		server_name www.1.com;
		ssl_certificate      cert.pem; //证书文件
    	ssl_certificate_key  cert.key; //证书文件

    	ssl_session_cache    shared:SSL:1m;
   		ssl_session_timeout  5m;

    	ssl_ciphers  HIGH:!aNULL:!MD5;
    	ssl_prefer_server_ciphers  on;
	    	
    	location / {
	    }
	}
	自定义ssl证书;测试用,正式环境使用需要到正规机构申请证书
	cd etc/pki/tls/certs/
	make cert.pem
	将生成的cert.pem文件复制到nginx的conf目录下

5、rewrite规则
    1、实现URL重定向的重要指令,他根据正则表达式来匹配内容跳转到另一个地址,结尾是flag标记
        flag参数:
            last	本条规则匹配完成后继续向下匹配新的location URI规则
            break	本条规则匹配完成后终止,不在匹配任何规则
            redirect	返回302临时重定向
            permanent	返回301永久重定向
	server {
		listen 80;
		server_name www.1.com;
		rewrite ^/(.*)$ https://www.baidu.com/$1 permanent; 所有的请求 $1表示$1后面的路径不会被重定向
        ($1|$2|$3 ...是nginx在匹配正则时生成的变量,用于捕获一个正则表达式括号中匹配的字符串(从左到右依次存储在$1|$2|$3 ...中),新值覆盖旧值。)
		rewrite ^/bbs$ http://bbs.baidu.com permanent; 以bbs结尾的
		rewrite ^/bbs/(.*)$ http://bbs.baidu.com/$1 permanent; 包含bbs的
		if ($host = "www.w.com") {
			rewrite ^/(.*)$ http://www.1.com/$1 permanent; permanent表示永久重定向301
		}
        #如果是http请求则转发到https上
        if ($scheme = http) {
			rewrite ^/(.*)$ https://$host:$server_port/$1 permanent;
		}

	}
6、防盗链
	location ~* \.(git|jpg|png|jpeg)$ {
		root /web;
		valid_referers none blocked www.westos.org; 以www.westos.org的域名访问时才能访问到图片
		if ($invalid_referer) {
			#return 403;
			rewrite ~/ http://bbs.wesos.org/daolian.jpg;
		}
	}

nginx配置反爬虫

server {
   location / {
       if ($http_user_agent ~* (Scrapy|Curl|HttpClient)) {
     	     return 403; 
       } 

	   #禁止指定UA及UA为空的访问 
    	if ($http_user_agent ~ "WinHttp|WebZIP|FetchURL|node-superagent|java/|FeedDemon|Jullo|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|Java|Feedly|Apache-HttpAsyncClient|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|oBot|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|HttpClient|MJ12bot|heritrix|EasouSpider|Ezooms|BOT/0.1|YandexBot|FlightDeckReports|Linguee Bot|^$" ) { 
	          return 403;              
    	} 
		 
	    #禁止非GET|HEAD|POST方式的抓取 
    	if ($request_method !~ ^(GET|HEAD|POST)$) { 
	       return 403; 
    	} 
   }
}

url重写:try_files

server {
    location / {
	    root /www;
	    index index.php index.html;
	    try_files $uri /index.php?$uri;
    }
}

反向代理

server {
    location ~ \.(jpg|jpeg|png|gif) {
		proxy_pass http://192.168.1.11:80;
        proxy_set_header Host $host;
        #反向代理时,获取用户的真实IP
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
	}
}
proxy_pass http://192.168.1.11:80/ 表示绝对根路径,不会带上匹配上的路径;没有/ 表示相对路径 会带上匹配的路径
#如果当前位置没有设置 proxy_set_header,那么会从上级继承,如果设置了,那么上级的设置将会失效

集群(负载均衡)

upstream servers {
	server 192.168.1.100:80 weight=1 max_fails=2 fail_timeout=30s; weight权重  max_fail最大失败次数,fail_timeout 失败错误时间 连接不上时ngixn会把此服务器剔除组,backup:标记该服务器为备用服务器。当主服务器停止时,请求会被发送到它这里。down:标记服务器永久停机了。
	server 192.168.1.100:81 weight=1 max_fails=2 fail_timeout=30s;
}
server {
	location / {
		root /www;
		index index.php;
		proxy_pass http://servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_connect_timeout   100s;   
		proxy_send_timeout      100s;  
		proxy_read_timeout      300s;
	}
}
负载后在日志格式log_format中添加$upstream_addr变量,可以显示出负载的服务器
负载均衡算法:
	fair  比 weight、ip_hash更加智能的负载均衡算法,fair算法可以根据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间 来分配请求,响应时间短的优先分配。Nginx本身不支持fair,如果需要这种调度算法,则必须安装upstream_fair模块。
    url_hash 基于url 按照访问的URL的hash结果分配请求,相同的URL会访问同一个后端服务器,在一定程度上可以提高缓存的效率,Nginx本身不支持url_hash,如果需要这种调度算法,则必须安装Nginx的hash软件包
    ip_hash 根据客户端IP地址在服务器之间分配请求。客户端IPv4地址的前三个八位位组或整个IPv6地址用作哈希密钥。确保来自同一客户端的请求将始终传递到同一服务器,在一定程度上解决了集群部署环境下Session共享的问题
    least_conn 将请求传递到活动连接数最少的服务器,同时要考虑服务器的权重。如果有多个这样的服务器,则依次使用加权循环平衡方法尝试它们。
    

缓存配置

#跟后端服务器连接的超时时间_发起握手等候响应超时时间
proxy_connect_timeout 500;
#连接成功后_等候后端服务器响应的时间_其实已经进入后端的排队之中等候处理
proxy_read_timeout 600;
#后端服务器数据回传时间_就是在规定时间内后端服务器必须传完所有数据
proxy_send_timeout 500;
#代理请求缓存区_这个缓存区间会保存用户的头信息以供Nginx进行规则处理_一般只要能保存下头信息即可  
proxy_buffer_size 128k;
#同上 告诉Nginx保存单个用的几个Buffer最大用多大空间
proxy_buffers 4 128k;
#如果系统很忙的时候可以申请更大的proxy_buffers 官方推荐*2
proxy_busy_buffers_size 256k;
#proxy缓存临时文件的大小
proxy_temp_file_write_size 128k;
#用于指定本地目录来缓冲较大的代理请求
proxy_temp_path /usr/local/nginx/temp;
#设置web缓存区名为cache_one,内存缓存空间大小为200M,自动清除超过15天没有被访问过的缓存数据,最大cache空间,如果不指定,会使用掉所有disk space,当达到配额后,会删除最少使用的cache文件30g;levels=1:2代表缓存的目录结构为2级目录,缓存会在/usr/local/nginx/cache目录下生成,包含2级目录,在之下就是缓存文件,测试的时候可以到该目录下查看缓存文件是否生成
proxy_cache_path /usr/local/nginx/cache levels=1:2 keys_zone=cache_one:200m inactive=15d max_size=30g;


location ^~/123/ {
    proxy_pass http://192.168.1.11:80;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
	#当上游服务器返回的响应是重定向或刷新请求(如HTTP响应码是301或者302)时,proxy_redirect可以重设HTTP头部的location或refresh字段。
	proxy_redirect off;
	#此处的cache_one必须于上一步配置的缓存区域名称相同
	proxy_cache cache_one;
	#不同的请求设置不同的缓存时效
	proxy_cache_valid 200 304 12h;
	proxy_cache_valid 301 302 1d;
	proxy_cache_valid any 1m;
	#生产缓存文件的key,通过4个string变量结合生成
	proxy_cache_key $uri$is_args$args;
	#其余类型的缓存时效为30天
	expires 30d;
}

注意:proxy_set_header Host $host 这一句可能导致缓存失败。

清除缓存:

缓存文件是根据proxy_cache_key这个指令生成的,所以找到对应的缓存文件,删除即可

location ~ /purge(/.*) {
    #删除指定缓存区域cache_one的特定缓存文件$uri$is_args$args
    proxy_cache_purge cache_one $uri$is_args$args;
    #运行本机和10.0.217.0网段的机器访问,拒绝其它所有  
    allow         127.0.0.1;
    allow         10.0.217.0/24;
    deny          all;
}

静态文件缓存配置:

location ~ .*\.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm)$
{
   expires      7d;
}
 
location ~ .*\.(?:js|css)$
{
   expires      7d;
}

location ~ .*\.(?:htm|html)$
{
    add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
}

location ^~/mobile/
{
    alias /app/xxx/html/mobile/;
    # 当请求转发时在转发的位置进行缓存配置
    if ($request_filename ~* .*\.(?:htm|html)$)
    {
        add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
    }
    if ($request_filename ~* .*\.(?:js|css)$)
    {
       expires      7d;
    }
 
    if ($request_filename ~* .*\.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm)$)
    {
       expires      7d;
    }
}

注意:html文件最容易碰到缓存问题,重新发版后,一旦客户端继续使用原来的缓存,那么在原来的缓存过期之前,没有任何办法去触使客户端更新,所以配置html缓存策略时要格外小心;

配置跨域请求

location / {  
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

    if ($request_method = 'OPTIONS') {
        return 204;
    }
} 

跨域信息解释:

1、Access-Control-Allow-Origin

服务器默认是不被允许跨域的。给Nginx服务器配置`Access-Control-Allow-Origin *`后,表示服务器可以接受所有的请求源(Origin),即接受所有跨域的请求。

2、Access-Control-Allow-Headers 是为了防止出现以下错误:

Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.

这个错误表示当前请求Content-Type的值不被支持。其实是我们发起了"application/json"的类型请求导致的。这里涉及到一个概念:预检请求(preflight request),请看下面"预检请求"的介绍。

3、 Access-Control-Allow-Methods 是为了防止出现以下错误:

Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.

4、给OPTIONS 添加 204的返回,是为了处理在发送POST请求时Nginx依然拒绝访问的错误

发送"预检请求"时,需要用到方法 OPTIONS ,所以服务器需要允许该方法。

5、 预检请求(preflight request)

其实上面的配置涉及到了一个W3C标准:CROS,全称是跨域资源共享 (Cross-origin resource sharing),它的提出就是为了解决跨域请求的。

跨域资源共享(CORS)标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。

其实Content-Type字段的类型为application/json的请求就是上面所说的搭配某些 MIME 类型的 POST 请求,CORS规定,Content-Type不属于以下MIME类型的,都属于预检请求:

application/x-www-form-urlencoded
multipart/form-data
text/plain

所以 application/json的请求 会在正式通信之前,增加一次"预检"请求,这次"预检"请求会带上头部信息 Access-Control-Request-Headers: Content-Type

OPTIONS /api/test HTTP/1.1
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
... 省略了一些

服务器回应时,返回的头部信息如果不包含Access-Control-Allow-Headers: Content-Type则表示不接受非默认的的Content-Type。即出现以下错误:

Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.

文章内容部分来源于:https://blog.csdn.net/zhuyu19911016520/article/details/90714429

                                  https://blog.csdn.net/zhangjunli/article/details/80436489

{/if}