67

我正在尝试将对 /api 的所有调用传递给我的 web 服务,但我不断收到以下配置的 404。按预期调用 / 返回 index.html。有谁知道为什么?

upstream backend{
    server localhost:8080;
}

 server {

    location /api {
        proxy_pass http://backend;
    }

    location / {
        root /html/dir;
    }
}

更多信息在这里

adept@HogWarts:/etc/nginx/sites-available$ curl -i localhost/api/authentication/check/user/email
HTTP/1.1 404 Not Found
Server: nginx/1.2.1
Date: Mon, 22 Apr 2013 22:49:03 GMT
Content-Length: 0
Connection: keep-alive

adept@HogWarts:/etc/nginx/sites-available$ curl -i localhost:8080/authentication/check/user/email
HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 22 Apr 2013 22:49:20 GMT
Transfer-Encoding: chunked

{"user":["false"],"emailAddress":["false"]}
4

6 回答 6

144

这个

location /api {
    proxy_pass http://backend;
}

需要是这个

location /api/ {
    proxy_pass http://backend/;
}
于 2013-04-22T23:43:31.120 回答
42

只是想提醒其他人,您的 proxy_pass url 后面的斜杠(backend*/*)非常重要!

如果配置是

location /api/ {
    proxy_pass http://backend;
}

而你访问http://abc.xyz/api/endpoint,你会被引导到http://backend/api/endpoint

如果配置是

location /api/ {
    proxy_pass http://backend/;
}

而你访问http://abc.xyz/api/endpoint,你会被引导到 http://backend/endpoint

这就是区别。

更多可参考:Nginx反向代理返回404

于 2020-07-06T09:35:08.210 回答
13

由于某种原因,Nginx 中的 proxy_pass 在传递到上游之前会削减标头“Host”,并且默认服务器会捕获请求,甚至 proxy_header_pass 也无济于事,因此我必须明确设置它:

location / {
    proxy_set_header Host $host;
    proxy_pass  http://backend;
}
于 2014-11-15T08:50:16.823 回答
2

尝试逐步排除故障,以确定可能导致问题的点。以下是一些可能的错误:

Nginx 配置更改但 Nginx 没有重新加载它

当您覆盖nginx.conf文件但没有触发 nginx 重新加载配置时,可能会发生这种情况。可能经常发生在 docker 用户身上。
要重新加载 nginx 配置,在 Nginx 主机中,执行命令:nginx -s reload
使用dockerdocker exec <container_name> nginx -s reload
: 参考:在运行时控制 NGINX 进程

Nginx 默认配置覆盖了你的

nginx.conf还包含默认 Nginx 配置并且它意外覆盖您的配置时,可能会发生这种情况,请仔细检查您nginx.conf是否包含任何默认配置路径。
例如:include /etc/nginx/conf.d/*.conf;,它还将在以下地址加载 nginx 默认配置如果是这种情况,请从您的文件 中注释掉(或删除)此配置语句。
在此处输入图像描述
includenginx.conf

验证 Nginx 配置

使用 command 验证实际应用的配置nginx -T,这将触发 Nginx 测试并打印出配置,检查配置输出是否符合您的预期结果:
参考:Nginx 命令行
您应该看到类似以下内容

root@22a2e5de75ba:/etc/nginx/conf.d# nginx -T
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# configuration file /etc/nginx/nginx.conf:
user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

http {
    server {
        server_name "localhost";
        listen 80;
        location /todo_server/ {
            proxy_pass http://jsonplaceholder.typicode.com;
        }
    }
    # 
    
    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;
    keepalive_timeout  65;
    #gzip  on;
    # include /etc/nginx/conf.d/*.conf;
}

Nginxproxy_pass配置问题

与此线程中的先前答案类似,如果您在 URI 末尾
指定尾部斜杠,这将导致意外的代理映射。 首先,看完整的:Nginx proxy_pass 文档 ,我将使用jsonplaceholder的 API进行演示(它实际上是为您提供响应来测试)/

http://jsonplaceholder.typicode.com/todos/

带有斜杠
末尾的斜杠表示该proxy_pass指令是用 URI 指定的。在这种情况下,当请求被传递到服务器时,与位置匹配的规范化请求 URI 的部分将被指令中指定的 URI 替换。

示例:使用以下配置(被理解为使用 URI 指定)将导致此映射

location /path1/ {
    proxy_pass http://jsonplaceholder.typicode.com/todos/;  
    # Requesting http://localhost:8080/path1/ will proxy to => http://jsonplaceholder.typicode.com/todos/
    # Requesting http://localhost:8080/path1/1/ will proxy to => http://jsonplaceholder.typicode.com/todos/1
}

location /path2/ {
    proxy_pass http://jsonplaceholder.typicode.com/;
    # Requesting http://localhost:8080/path2/todos/ will proxy to => http://jsonplaceholder.typicode.com/todos/
}

不带斜杠
不带斜杠/,理解为无 URI 方案,将请求 URI 以与处理原始请求时客户端发送的相同形式传递给服务器,或者在处理请求时传递完整规范化的请求 URI更改了 URI。

location /todos/ {
    proxy_pass http://jsonplaceholder.typicode.com; 
    # Requesting : http://localhost:8080/todos/ will proxy to ==> http://jsonplaceholder.typicode.com/todos/
    # Requesting : http://localhost:8080/todos/1 will proxy to ==> http://jsonplaceholder.typicode.com/todos/1
}

另请参阅@dayo的完整答案以及Richard Smith 的答案

于 2021-06-26T15:41:16.233 回答
2

我忘了在 PORT 80 上听,修好了。

nginx 配置的“http”部分,位于:/etc/nginx/nginx.conf,如下:

http {
    server {
        listen 192.111.111.11:80;
        location /path1/ {
            proxy_pass http://127.0.0.1:3000/path1/
        }
    }
}

现在,访问
http://192.111.111.11/path1/
将得到访问
http://127.0.0.1:3000/path1/的结果

注意:
将 192.111.111.11 替换为上面的 IP 地址。
运行“ifconfig”命令,“inet addr”部分会给出你的IP地址

于 2015-08-19T05:40:31.623 回答
2

请检查您是否default.confsite-enabled文件夹中删除了文件。如果您在基于 debian 的 ubuntu 系统中,请运行该命令

sudo rm /etc/nginx/sites-enabled/default

它对我有用。

于 2021-05-01T16:51:51.057 回答