网管把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'
相关推荐
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ2 分钟前
nginx部署教程
运维·网络·nginx
雪隐10 分钟前
个人电脑玩AI00-前言
人工智能·后端
我是一颗柠檬21 分钟前
【Java后端技术亮点】动态路由权限(按钮级权限),细粒度控制到按钮级别
java·开发语言·后端·状态模式
蚰蜒螟23 分钟前
走进 Linux 内核:从 touch 命令到磁盘 inode 的完整旅程
java·linux·前端
feng_you_ying_li24 分钟前
liunx之可重入函数,volatite,和线程的基本介绍(1)
linux
前端Hardy27 分钟前
CSS 动画真的比 JS 快?Josh Comeau 做了组实验,结果跟直觉不一样
前端·javascript·后端
Front思28 分钟前
调取支付宝支付正式环境不可以唤起来,但是沙箱可以
后端
兮山与28 分钟前
Linux
linux·javaee进阶
foggyprojects34 分钟前
AI 生成 SQL 模板以后,为什么还需要固定 helper 规则
后端
明天一点35 分钟前
Cloudflare 通知转发钉钉机器人
前端·后端