如何配置 nginx 反向代理,重写路径?

如何配置 nginx 反向代理,重写路径?

nginx反向代理路径问题 http://abc.com:8080 写法和 http://abc.com:8080/ 写法的区别如下:

  # 不带/
  location /NginxTest/ {
      proxy_pass  http://abc.com:8080;
  }
  # 带/
  location /NginxTest/ {
      proxy_pass  http://abc.com:8080/;
  }

上面两种配置,区别只在于proxy_pass转发的路径后是否带 “/”

针对情况1:

  • (带参数)访问 http://abc.com:8080/NginxTest/servlet/MyServlet?name=123333333 ,则被nginx代理后,请求路径便会访问 http://abc.com:8080/NginxTest/servlet/MyServlet?name=123333333

  • (不带参)访问 http://abc.com/NginxTest/servlet/MyServlet ,则被nginx代理后,请求路径便会访问 http://abc.com:8080/NginxTest/servlet/MyServlet

针对情况2:

  • 访问 http://abc.com:8080/NginxTest/test.jsp,则被nginx代理后,请求路径会变为 http://abc.com:8080/test.jsp ,直接访问server的根资源。

  • 访问 http://abc.com:8080/NginxTest/NginxTest/NginxTest/servlet/MyServlet ,被nginx代理后,请求路径才会访问 http://abc.com:8080/NginxTest/servlet/MyServlet

注意:上面两种访问路径的差别。修改配置后重启nginx代理就成功了

Nginx地址重写

Rewrite的语法:

rewrite regex URL [flag];

rewrite是关键字,regex是正则表达式,URL是要替代的内容,[flag]是标记位的意思,它有以下几种值:

  • last: 相当于Apache的[L]标记,表示完成rewrite
  • break: 停止执行当前虚拟主机的后续rewrite指令集
  • redirect: 返回302临时重定向,地址栏会显示跳转后的地址
  • permanent: 返回301永久重定向,地址栏会显示跳转后的地址
  location /NginxTest/ {
      rewrite  ^/NginxTest/(.*)$  /$1  break;
      proxy_pass  http://abc.com:8080;
  }
  1. ^~/NginxTest/ 是一个匹配规则,用于拦截请求,匹配任何以 /NginxTest/ 开头的地址,匹配符合以后就停止往下搜索正则;

  2. rewrite ^/NginxTest/(.*)$ /$1 break;代表重写拦截进来的请求,并且只能对域名后边的除去传递的参数外的字符串起作用。例如:http://abc.com:8080/NginxTest/NginxTest/servlet/MyServlet?name=lovleovlove 重写,只对 /NginxTest/NginxTest/servlet/MyServlet 重写。

  • 访问地址:http://abc.com:8080/NginxTest/NginxTest/servlet/MyServlet?name=lovleovlove , 实际访问的地址(重写地址)为 http://abc.com:8080/NginxTest/servlet/MyServlet?name=lovleovlove

  • 访问地址:http://abc.com:8080/NginxTest/NginxTest/servlet/MyServlet ,实际访问的地址(重写地址)为 http://abc.com:8080/NginxTest/servlet/MyServlet

  1. rewrite后面的参数是一个简单的正则^/NginxTest/(.*)$ /$1 ,$1代表正则中的第一个(),$2代表第二个()的值,以此类推。break代表匹配一个之后停止匹配。

配置样例

  • 全局配置
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;
    keepalive_timeout  65;

    gzip  on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;

    include /etc/nginx/conf.d/*.conf;
}
  • http请求的配置样例
upstream gateway_upstream {
    server 127.0.0.1:8760 fail_timeout=0;
}
upstream jenkins_upstream {
    server 127.0.0.1:8080 fail_timeout=0;
}

server {
    listen       80;
    server_name  localhost;    #没有域名就写localhost

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the jenkins scripts to Apache listening on 127.0.0.1:8080
    #
    location /jenkins {
        proxy_pass   http://jenkins_upstream/jenkins;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location ^~ /api/ {
        proxy_pass   http://gateway_upstream/;
        proxy_set_header Host $host;
        # proxy_set_header X-Real-IP $remote_addr;
        # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

}
  • https请求配置样例
server {
    listen      80;
    listen	[::]:80;
    server_name  abeille.top www.abeille.top;  # 域名

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    # redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
    return 301 https://$host$request_uri;
}

upstream jenkins_upstream {
    server 127.0.0.1:8080 fail_timeout=0;
}

upstream gateway_upstream {
    server 127.0.0.1:8760 fail_timeout=0;
}

server {
    listen         443 default ssl http2;
    listen         [::]:443 default ssl http2;
    server_name    abeille.top www.abeille.top;  # 域名

    ssl_certificate     302xxxw.abeille.top.pem;   # 证书,放置路径再/etc/nginx下
    ssl_certificate_key 302xxxw.abeille.top.key;   # 证书的密钥
    ssl_session_timeout 5m;

    ssl_session_cache	shared:MozSSL:10m;  # about 40000 sessions

    # modern configuration
    ssl_protocols TLSv1.3;
    ssl_prefer_server_ciphers off;

    add_header Strict-Transport-Security "max-age=63072000" always;	# HSTS策略
    add_header X-Frame-Options DENY;					# 减少点击劫持
    add_header X-Content-Type-Options nosniff; 				#禁止服务器自动解析资源类型
    add_header X-Xss-Protection 1;				        #防XSS攻击

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;

    error_page   500 502 503 504  /50x.html;    # 错误页50x
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location ^~ /jenkins {
        proxy_pass              http://jenkins_upstream/jenkins;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location ^~ /api/ {  			# 这里的配置/api/前缀会在匹配后忽略掉,但是需要配合proxy_pass设置,在路径后添加"/"后缀
        proxy_pass       http://gateway_upstream/;
        proxy_set_header Host $host;    	# 这个配置必须添加,否则会出现nginx 400
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location / {
        root   /usr/share/nginx/dist;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html last;  # 解决vue路由再刷新404
    }
}