网管把PUT请求禁掉非说是我们接口的问题---nginx 请求转发就完了?各种奇技淫巧等你来

开发是项目的成型的第一步,项目内部、外部统一话接口还得借助nginx 这种请求转发工具,因为你无法保证项目的单一性,我们整个项目可能用到各种各样的技术。

Nginx配置proxy_pass转发的/路径问题

在nginx中配置proxy_pass时,如果是按照^~匹配路径时,要注意proxy_pass后的url最后的/,当加上了/,相当于是绝对根路径,则nginx不会把location中匹配的路径部分代理走;如果没有/,则会把匹配的路径部分也给代理走。

ini 复制代码
location ^~ /static_js/ 
{ 
proxy_cache js_cache; 
proxy_set_header Host js.test.com; 
proxy_pass http://js.test.com/; 
}

如上面的配置,如果请求的url是http://servername/static_js/test.html 会被代理成js.test.com/test.html

而如果这么配置

nginx 复制代码
location ^~ /static_js/ 
{ 
proxy_cache js_cache; 
proxy_set_header Host js.test.com; 
proxy_pass http://js.test.com; 
}

则会被代理到js.test.com/static_js/t...

root alias 区别

nginx 复制代码
location /test/{
    root /home/china/areas/;
}

访问 localhost***/test/hello.html实际访问的是 /home/china/areas/test/hello.html

nginx 复制代码
location /tets/{
    alias /home/china/areas/;
}

访问 localhost***/test/hello.html实际访问的是 /home/china/areas/hello.html

server_name 的使用

  • 之前我一直认为这里的 server_name 就是方便我们访问的域名。其实并不是这么回事。不信你配置好之后在浏览器中访问根本是访问不同的。

  • 首先我们得明白我们请求的域名是需要经过 DNS 解析的。和 nginx 是无关的。本地的 DNS 解析就是本地的 /etc/hosts 文件。

ini 复制代码
server {
  listen 88;
  listen [::]:88;

  server_name www.zxhtom.com;

  root /var/www/html;
  index index.html;

  location / {
    try_files $uri $uri/ =404;
  }
}

server {
  listen 88;
  listen [::]:88;

  server_name www.zxhtom.cn;

  root /var/www/example.com;
  index index.html;

  location / {
    try_files $uri $uri/ =404;
  }
}
  • 上面我配置了两个 server 可能你会觉得奇怪,为什么两个 server 都是监听88端口呢?仔细观察你会发现他们的 server_name 不同。

  • 接下来我们在本地配置这两个域名的解析

    127.0.0.1 www.zxhtom.com
    127.0.0.1 www.zxhtom.cn

  • 访问两个域名对应的 88端口,我们能够发现对应的是不同的页面。到这里你应该明白 server_name 的作用的吧。

  • 上述的配置同时对 127.0.0.1 的使用也没啥影响。
  • 配置了专属域名如果此时 hosts 文件中配置了另外一个域名 www.zxhtom.store 那么是否还需要在另行配置呢?答案是否定的。
  • 当出现新的域名访问 nginx 的时候,nginx 会去寻找配置了 default_server 的 server 。如上我们两个 server 都没有配置 default_server . nginx 会按照顺序选取第一个。换句话说我们 www.zxhtom.store 对应的是 www.zxhtom.com server_name 的配置。如果我们想让 www.zxhtom.cn 作为默认的,我们可以将他配置在地一个。或者修改成如下配置
nginx 复制代码
server {
  listen 80 default_server;
  listen [::]:80 default_server;

  server_name www.zxhtom.cn;
  charset utf-8;
  root /home/zxhtom/temp/html;
  index index.html;
}

中文乱码

  • 上面我们能够发现,我们自定义的页面显示的是乱码。

SSL

  • google 浏览器带头限制 http 请求,关于网站 SSL 证书的配置尤为重要。下面我们通过 nginx 来配置下 SSL
  • 阿里云域名服务地方可以申请免费的 SSL 证书。申请之后可以按照阿里官方的教程配置
config 复制代码
server {
	# SSL configuration
	#
	listen 443 ssl ;
	listen [::]:443 ssl ;
  server_name www.zxhtom.cn;
  #填写证书文件名称
  ssl_certificate cert/<domain_name>.pem;
  #填写证书私钥文件名称
  ssl_certificate_key cert/<domain_name>.key;

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

  #默认加密套件
  ssl_ciphers HIGH:!aNULL:!MD5;

  #自定义设置使用的TLS协议的类型以及加密套件(以下为配置示例,请您自行评估是否需要配置)
  #TLS协议版本越高,HTTPS通信的安全性越高,但是相较于低版本TLS协议,高版本TLS协议对浏览器的兼容性较差。
  #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
  #ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;

  #表示优先使用服务端加密套件。默认开启
  ssl_prefer_server_ciphers on;

  location / {

    default_type application/json;
    return 200 '{"status":"success","result":"welcom https cn"}';
    # try_files $uri $uri/ =404;
    # proxy_pass http://192.168.0.190;
  }
}
  • 结合上面我们描述的 server_name 的功能,我们上述的配置就是支持 https://www.zxhtom.cn 的请求访问。当我们访问该地址就会返回 welcom https cn 等信息。

接口 413 错误

  • 413 Request Entity Too Large 。根据提示第一反应就是请求体过大。但是我的报错是 GET 请求,仔细观察下 GET 请求没啥参数传递的。不管三七二十一先按照网上的进行修改下。
nginx 复制代码
413 Request Entity Too Large
nginx 复制代码
location /zxhtom/latest/{
	proxy_set_header Host $http_host;
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header REMOTE-HOST $remote_addr;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	client_max_body_size 800m;
	proxy_pass http://www.zxhtom.com/;
}
  • 只需要添加 client_max_body_size 参数即可放开我们请求体的数据了。但是还是解决不了我的问题,而且 client_max_body_size 根绝名字猜测应该是请求数据大小的设置,应该主要使用的场景是文件上传才需要设置,正常数据怎么会有几百 M 呢?
  • 在分析下自己的数据发现因为接口需要登录请求头中 JWT 的 token 特别的长。于是搜索了下 nginx 是否可以调整请求头大小。
nginx 复制代码
client_header_buffer_size 16k;
large_client_header_buffers 4 16k;
  • 设置了之后还是不行,于是将焦点下放到网关层面上 http://www.zxhtom.com。于是我跳过 nginx 单独访问网管发现报错 400 。他的报错突然让我坚定了自己的猜想,我们的网关是通过 SpringCloud Gateway 实现的。
java 复制代码
server:
	max-http-header-size: 2MB
java 复制代码
@Component
public class NettyConfiguration implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {

    @Override
    public void customize(NettyReactiveWebServerFactory container) {
        container.addServerCustomizers(
                httpServer -> httpServer.httpRequestDecoder(
                        httpRequestDecoderSpec -> httpRequestDecoderSpec.maxHeaderSize(1000485760)
                )
        );
    }

}
  • 在网关中添加如上配置即可解决 413 问题。

PUT/DELETE 接口 Empty reply

  • 由于政务系统对安全性的要求,在他们网络层面上将 PUT 、DELETE 这两种请求给禁掉了。而我们系统中存在大面积的这样的请求,如果改的话工作量巨大而且容易遗漏,后来找到一中通过 nginx 转发的方案来解决这个问题。
nginx 复制代码
set $method $request_method;
      if ($http_X_HTTP_Method_Override ~* 'DELETE'){
       set $method DELETE;

      }
      if ($http_X_HTTP_Method_Override ~* 'PUT'){
       set $method PUT;

      }
      proxy_method $method;
  • 加上上面这段配置后重启 nginx ,原本的 PUT 接口我们只需要修改为 POST,并且请求头中添加 X-HTTP-Method-Override:PUT 即可。
shell 复制代码
curl -XPUT 'http://www.zxhtom.com/pre/userList'
  • 只需要改为
shell 复制代码
curl -XPOST 'http://www.zxhtom.com/pre/userList' -H'X-HTTP-Method-Override:PUT'
相关推荐
是真的小外套22 分钟前
第十五章:XXE漏洞攻防与其他漏洞全解析
后端·计算机网络·php
原来是猿32 分钟前
Linux进程信号详解(二):信号产生
linux·运维·服务器
chxii34 分钟前
Nginx性能优化-压缩(返回头报文介绍)
运维·nginx·性能优化
Bert.Cai1 小时前
Linux cd命令详解
linux·运维
扑火的小飞蛾2 小时前
Kali Linux 安装 OpenClaw 详细教程
linux·运维·服务器
ybwycx2 小时前
SpringBoot下获取resources目录下文件的常用方法
java·spring boot·后端
王琦03182 小时前
第二次作业
linux·运维·服务器
Bert.Cai2 小时前
Linux mkdir命令详解
linux·运维
超绝振刀怪2 小时前
【Linux进程状态:僵尸进程、孤儿进程和调度基础】
linux·僵尸进程·孤儿进程·进程状态
小陈工2 小时前
Python Web开发入门(十一):RESTful API设计原则与最佳实践——让你的API既优雅又好用
开发语言·前端·人工智能·后端·python·安全·restful