Wenn in der URL kein abschließender Schrägstrich vorhanden ist, versucht Nginx, JS vom falschen Ort zu laden.

Wenn in der URL kein abschließender Schrägstrich vorhanden ist, versucht Nginx, JS vom falschen Ort zu laden.

Ich habe eine Nginx API Gateway-Konfiguration eingerichtet, die der hier gezeigten ähnelt.Hier. Die Anwendung wird unter „www.foo.com/bar/app/“ bereitgestellt, wir möchten jedoch, dass Benutzer die Website auch ohne den abschließenden Schrägstrich besuchen können.

Wenn ich derzeit die URL ohne den abschließenden Schrägstrich besuche, gibt der Server einen 500-Fehler aus. Ein Blick in die Protokolle zeigt Folgendes:

2021/01/05 22:43:39 [notice] 22#22: *4 rewritten data: "/", args: "", client: 172.29.0.1, server: , request: "GET /bar/app HTTP/1.1", host: "localhost:8080"
2021/01/05 22:43:39 [error] 22#22: *4 open() "/etc/nginx/html/nap/js/compiled/app.js" failed (2: No such file or directory), client: 172.29.0.1, server: , request: "GET /bar/js/compiled/app.js HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/bar/app"

Wenn die URL hingegen einen Schrägstrich am Ende hat, zeigt das Protokoll die folgende Sequenz an:

2021/01/05 22:33:55 [notice] 22#22: *1 rewritten data: "//", args: "", client: 172.29.0.1, server: , request: "GET /bar/app/ HTTP/1.1", host: "localhost:8080"
2021/01/05 22:33:55 [notice] 22#22: *1 "^/bar/app(.*)$" matches "/bar/app/js/compiled/app.js", client: 172.29.0.1, server: , request: "GET /bar/app/js/compiled/app.js HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/bar/app/"

Die API-Definition + Richtlinie derzeit:

location /bar/app {
    set $upstream bar_frontend_app_main;
    rewrite ^/bar/app(.*)$ /_bar_frontend_app_service$1 last;
}

location /_bar_frontend_app_service {
    internal;
    set $api_name "Frontend API";

    rewrite ^/_bar_frontend_app_service(.*)$ /$1 break; 
    proxy_pass http://$upstream;      # Proxy the rewritten URI
}

und hier ist die vollständige Konfiguration:

events {
    worker_connections  1024;
}

http {
    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"';

    # Added to troubleshoot trailing slash frontend issue
    log_format upstream_logging '[$time_local] $remote_addr - $remote_user - $server_name to: '
                                '$upstream: $request upstream_response_time $upstream_response_time '
                                'msec $msec request_time $request_time';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;

    keepalive_timeout  65;

    include /etc/nginx/api_gateway.conf; # All API gateway configuration
    include /etc/nginx/conf.d/*.conf;    # Regular web traffic
}

# configuration file /etc/nginx/mime.types:

types {
    ...
}

# configuration file /etc/nginx/api_gateway.conf:
log_format api_main '$remote_addr - $remote_user [$time_local] "$request"'
                    '$status $body_bytes_sent "$http_referer" "$http_user_agent"'
                    '"$http_x_forwarded_for" "$api_name"';

include api_backends.conf;

server {
    set $api_name -; # Start with an undefined API name, each API will update this value
    access_log /var/log/nginx/api_access.log api_main; # Each API may also log to a separate file

    listen 80;

    # API definitions, one per file
    include api_conf.d/*.conf;

    # Error responses
    error_page 404 = @400;         # Invalid paths are treated as bad requests
    proxy_intercept_errors on;     # Do not send backend errors to the client
    include api_json_errors.conf;  # API client friendly JSON error responses
    default_type application/json; # If no content-type then assume JSON

    proxy_http_version 1.1;
    proxy_set_header Connection "";
    rewrite_log on; 
}


# configuration file /etc/nginx/api_backends.conf:

upstream foo_api_main {
    keepalive 32;
    zone foo_service 64k;
    server foo-server:5000;
}

upstream foobar_api_main {
    keepalive 32;
    zone foobar_service 64k;
    server foobar:5000;
}

upstream bar_frontend_app_main {
    keepalive 32;
    zone bar_frontend_app_service 64k;
    server bar-frontend:80;
}

# configuration file /etc/nginx/api_conf.d/foo_api.conf:
# API definition
#

location /api/hello/foo {
   set $upstream foo_api_main;
   rewrite ^/api/hello/foo/(.*)$ /_foo_service$1 last;
}

# This is used when app is running through MAF
location /hello/foo {
   set $upstream foo_api_main;
   rewrite ^/hello/foo/(.*)$ /_foo_service$1 last;
}


# Policy section
#
location /_foo_service {
    internal;
    set $api_name "foo backend API";

    rewrite ^/_foo_service(.*)$ /api/$1 break; # Remove /_foo_service prefix
    proxy_pass http://$upstream;      # Proxy the rewritten URI
}


# configuration file /etc/nginx/api_conf.d/bar_frontend.conf:

location /bar/app {
    set $upstream bar_frontend_app_main;
    rewrite ^/bar/app(.*)$ /_bar_frontend_app_service$1 last;
}

# Policy section
#
location /_bar_frontend_app_service {
    internal;
    set $api_name "Frontend API";

    rewrite ^/_bar_frontend_app_service(.*)$ /$1 break; 
    proxy_pass http://$upstream;      # Proxy the rewritten URI
}


# configuration file /etc/nginx/api_conf.d/foobar_api.conf:
# API definition
#
location /api/hello/foobar {
    set $upstream foobar_api_main;
    rewrite ^/api/hello/foobar/(.*)$ /_foobar_service$1 last;
}

# This is used when app is running through MAF
location /hello/foobar {
   set $upstream foobar_api_main;
   rewrite ^/hello/foobar/(.*)$ /_foobar_service$1 last;
}


# Policy section
location /_foobar_service {
    internal;
    set $api_name "foobar backend API";

    rewrite ^/_foobar_service(.*)$ /$1 break; # Remove /_foobar_service prefix
    proxy_pass http://$upstream;      # Proxy the rewritten URI
}


# configuration file /etc/nginx/api_json_errors.conf:
error_page 400 = @400;
location @400 { return 400 '{"status":400,"message":"Bad request"}\n'; }

error_page 401 = @401;
location @401 { return 401 '{"status":401,"message":"Unauthorized"}\n'; }

error_page 403 = @403;
location @403 { return 403 '{"status":403,"message":"Forbidden"}\n'; }

error_page 404 = @404;
location @404 { return 404 '{"status":404,"message":"Resource not found"}\n'; }

error_page 405 = @405;
location @405 { return 405 '{"status":405,"message":"Method not allowed"}\n'; }

error_page 408 = @408;
location @408 { return 408 '{"status":408,"message":"Request timeout"}\n'; }

error_page 413 = @413;
location @413 { return 413 '{"status":413,"message":"Payload too large"}\n'; }

error_page 414 = @414;
location @414 { return 414 '{"status":414,"message":"Request URI too large"}\n'; }

error_page 415 = @415;
location @415 { return 415 '{"status":415,"message":"Unsupported media type"}\n'; }

error_page 426 = @426;
location @426 { return 426 '{"status":426,"message":"HTTP request was sent to HTTPS port"}\n'; }

error_page 429 = @429;
location @429 { return 429 '{"status":429,"message":"API rate limit exceeded"}\n'; }

error_page 495 = @495;
location @495 { return 495 '{"status":495,"message":"Client certificate authentication error"}\n'; }

error_page 496 = @496;
location @496 { return 496 '{"status":496,"message":"Client certificate not presented"}\n'; }

error_page 497 = @497;
location @497 { return 497 '{"status":497,"message":"HTTP request was sent to mutual TLS port"}\n'; }

error_page 500 = @500;
location @500 { return 500 '{"status":500,"message":"Server error"}\n'; }

error_page 501 = @501;
location @501 { return 501 '{"status":501,"message":"Not implemented"}\n'; }

error_page 502 = @502;
location @502 { return 502 '{"status":502,"message":"Bad gateway"}\n'; }

verwandte Informationen