nginx proxy_pass 404错误,不明白为什么

时间:2013-04-22 22:35:19

标签: nginx

我试图将所有对/ api的调用传递给我的webservice但是我继续使用以下配置获得404s。按预期调用/返回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"]}

6 个答案:

答案 0 :(得分:71)

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

需要成为这个

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

答案 1 :(得分:10)

由于某种原因,Nginx 1.6.2中的proxy_pass在传递给上游之前削减了标题“Host”,并且默认服务器请求捕获,甚至proxy_header_pass也没有帮助,所以我要明确地设置它:

location / {
    proxy_set_header Host $host;
    proxy_pass  http://backend;
}

答案 2 :(得分:6)

只是想提醒其他人,proxy_pass网址后的斜杠(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 reverse proxy return 404

答案 3 :(得分:1)

我忘了听PORT 80,修好了。

“http”部分的nginx配置,位于:/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/

注意:
     用上面的IP地址替换192.111.111.11      运行“ifconfig”命令,“inet addr”部分将提供您的IP地址

答案 4 :(得分:1)

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

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

它对我有用。

答案 5 :(得分:0)

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

Nginx 配置改变了,但 Nginx 没有重新加载它

当您覆盖 nginx.conf 文件但未触发 nginx 重新加载配置时,可能会发生这种情况。 docker用户可能经常出现。
要重新加载 nginx 配置,请在 Nginx 主机中执行命令:nginx -s reload
使用泊坞窗:docker exec <container_name> nginx -s reload
参考:Controlling NGINX Processes at Runtime

Nginx 默认配置覆盖你的

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

验证 Nginx 配置

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

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;
}

Nginx proxy_pass 配置问题

类似于此线程中的上一个答案
如果您在 URI 的末尾指定尾部斜杠 /,这将导致意外的代理映射。
首先,查看完成的:Nginx proxy_pass document
我将使用 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 的the completed answer 还有answer by Richard Smith