允许 nginx 服务器中的 POST 请求获取静态内容

Sur*_*har 5 nginx static-content angular

我们有一个 Angular 应用程序部署到 DigitalOcean => Ubuntu => Nginx, => www 文件夹,它接受所有 GET 请求。我们调用一些第三方 API,作为响应,第三方通过 POST 访问我们的端点。但 nginx 不允许。它给出了 405 消息。我不是 nginx 专家,有人可以提供一些建议吗?

<html>
    <head>
        <title>405 Not Allowed</title>
    </head>
    <body bgcolor="white">
        <center>
            <h1>405 Not Allowed</h1>
        </center>
        <hr>
        <center>nginx/1.14.0 (Ubuntu)</center>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

小智 0

如果这个第 3 方碰巧在 POST 中向您发送了一些数据,并且您需要它在参数中使用相同的数据创建 GET,那么几天后我发现唯一的解决方案是使用 nginx 的 nfs 模块。

我正在使用带有 nginx 和 certbot 的 docker 映像,但它缺少 nfs,所以我必须扩展它:

docker 撰写

version: '3.9'
services:
  reverse:
    restart: unless-stopped
    #image: jonasal/nginx-certbot:3.3.1-nginx1.23.3
    build:
      context: .
      dockerfile: dockerfile
    image: <image_name>
    container_name: reverse
    env_file:
      - ./nginx-certbot.env
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./ssl_conf:/etc/letsencrypt
      - ./nginx/user_conf.d:/etc/nginx/user_conf.d
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/includes:/etc/nginx/includes/
      - ./logs:/var/log/nginx:rw
      - ./nginx/njs:/etc/nginx/njs/
Run Code Online (Sandbox Code Playgroud)

dockerfile(扩展 njs 包)

FROM jonasal/nginx-certbot:3.3.1-nginx1.23.3-alpine

RUN apk add nginx-module-njs
Run Code Online (Sandbox Code Playgroud)

在 nginxconf 中你必须添加

load_module modules/ngx_http_js_module.so;
load_module modules/ngx_stream_js_module.so;

http {
    ...
    js_path /etc/nginx/njs/;
    js_import main.js;
    ...
}
Run Code Online (Sandbox Code Playgroud)

现在您已准备好使用 njs 来操作数据。

创建一个 main.js,将 POST 有效负载存储在文件中,然后读取它

var fs = require('fs');
var STORAGE = "/tmp/njs_storage"

function save(r) {
    fs.writeFileSync(STORAGE, r.requestBody);
    r.internalRedirect("/readdirect")
}

function readdirect(r) {
    var data = "";
    try {
        data = fs.readFileSync(STORAGE);
    } catch (e) {
    }
    r.internalRedirect("/access?" + data)
}


export default {save, readdirect}
Run Code Online (Sandbox Code Playgroud)

和 nginx file.conf

    location / {
    include /etc/nginx/includes/common_location.conf;
    resolver 127.0.0.11 ipv6=off;
    set $upstream localhost:4200;
    proxy_pass http://$upstream;
}

location /apple {
    js_content main.save;
}

location /readdirect {
    js_content main.readdirect;
}

location = /access {
    include /etc/nginx/includes/common_location.conf;
    proxy_method GET;
    resolver 127.0.0.11 ipv6=off;
    rewrite ^ https://example.com/access/ break;
}
Run Code Online (Sandbox Code Playgroud)

所以现在基本上带有正文有效负载的 POST 会转换为带有 args ?code=1&state=2 的 GET 以在前端使用(并模仿其他社交登录的行为)。

找到正确的解决方案并不容易(尝试使用 LUA 进行扩展,但版本不匹配等),但值得麻烦