Получение ошибки 404 от сервера Nginx на странице входа в систему с вызовом javascript ajax в тот же домен - PullRequest
0 голосов
/ 09 июля 2020

Пожалуйста, помогите: -)

Я настраиваю свой веб-сервер с помощью NGINX, но остановился на ошибке, которая, похоже, связана с CORS .

В консоли браузера, когда я набираю: $ .get ("/ logon? Action = login"); и нажмите ENTER, он успешно выполнит запрос и вернет правильные данные.

Но если я наберу: $ .post ("/ logon? action = login"); и нажмите ENTER, это дает мне ошибку 404 / Not Found.

URL-адрес моего входа в систему выглядит следующим образом: https://www.mywebsite.com/logon

Где пользователь сообщает свой / ее учетные данные и нажимает кнопку отправки, которая запускает функцию «mySubmit ()».

<div>
  <input type='text' name='user'>
  <input type='password' name='password'>
  <button onclick='mySubmit'>Submit</button>
</div>

<script>
function mySubmit() {
    $.ajax({
        type: 'POST',
        url: '/logon?action=login',
        data: { user: 'john', password: 'secret' },
        async: false,
        error: function(err){
                console.log('err',err);
            },
        success: function(data) {
                console.log('success',data);
            }
    });
}
</script>

Используя Firefox Консоль, я вижу:

ЗАПРОС :

    POST /logon?action=login HTTP/2
    payload: user=john&password=secret

ЗАГОЛОВКИ ЗАПРОСА :

    Host: www.mywebsite.com
    Accept: */*
    Accept-Language: en-US;q=0.5,en;q=0.3
    Accept-Encoding: gzip, deflate, br
    Referer: https://www.mywebsite.com/logon
    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
    X-Requested-With: XMLHttpRequest
    Content-Length: 76
    Origin: https://www.mywebsite.com
    Connection: keep-alive
    Pragma: no-cache
    Cache-Control: no-cache
    TE: Trailers

ОТВЕТ :

    Status404
    Not Found
    VersionHTTP/2
    Transferred387 B (146 B size)

ЗАГОЛОВКИ ОТВЕТА :

    access-control-allow-credentials
        true
    access-control-allow-origin
        https://www.mywebsite.com
    content-encoding
        gzip
    content-type
        text/html
    date
        Thu, 09 Jul 2020 20:33:36 GMT
    vary
        Accept-Encoding

NGINX /var/log/access.log

123.123.123.123 - - [09/Jul/2020:17:31:49 -0300] "GET /logon HTTP/2.0" 200 4560 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0"
123.123.123.123 - - [09/Jul/2020:17:33:36 -0300] "POST /logon?action=login HTTP/2.0" 404 106 "https://www.mywebsite.com/logon" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0"

NGINX / usr / local /etc/nginx/conf.d/mywebsite.com.conf

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;

        server_name api.mywebsite.com assets.mywebsite.com www.mywebsite.com mywebsite.com;

        root /usr/local/share/www;
        index index.php;

        # SSL
        ssl_certificate /usr/local/etc/letsencrypt/live/mywebsite.com/cert.pem;
        ssl_certificate_key /usr/local/etc/letsencrypt/live/mywebsite.com/privkey.pem;

        access_log /var/log/nginx/mywebsite.com/access.log;
        error_log /var/log/nginx/mywebsite.com/error.log;

        # If request comes from allowed subdomain (*.mywebsite.com) then we enable CORS
        if ($http_origin ~* (https?://.*\.mywebsite\.com(:[0-9]+)?$)) {
           set $cors "1";
        }

        location / {
                try_files $uri $uri/ /index.php?$uri&$args;

                # OPTIONS indicates a CORS pre-flight request
                if ($request_method = 'OPTIONS') {
                        set $cors "${cors}o";
                }

                # Append CORS headers to any request from
                # allowed CORS domain, except OPTIONS
                if ($cors = "1") {
                        more_set_headers 'Access-Control-Allow-Origin: $http_origin';
                        more_set_headers 'Access-Control-Allow-Credentials: true';
                }

                # OPTIONS (pre-flight) request from allowed
                # CORS domain. return response directly
                if ($cors = "1o") {
                        more_set_headers 'Access-Control-Allow-Origin: $http_origin';
                        more_set_headers 'Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE';
                        more_set_headers 'Access-Control-Allow-Credentials: true';
                        more_set_headers 'Access-Control-Allow-Headers: Origin,Content-Type,Accept';
                        add_header Content-Length 0;
                        add_header Content-Type text/plain;
                        return 204;
                }

        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/var/run/php-fpm.socket;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $request_filename;
                fastcgi_param MYPARAM 'my-custom-value';
                include fastcgi_params;
        }

}

# Redirect all http to https
server {
        listen 80;
        listen [::]:80;
        server_name *.mywebsite.com;
        return 301 https://$host$request_uri;
}

Есть идеи?

Заранее спасибо! Франциско

1 Ответ

0 голосов
/ 13 июля 2020

ОБНОВЛЕНИЕ 2020-ИЮЛ-13

Что ж, на случай, если кто-то столкнется с той же проблемой, я расскажу, как мне удалось обойти проблему: я использовал конфигурацию error_page для запустить мой index. php и обработать ошибку 404 и вернуть код состояния 200.

NGINX /usr/local/etc/nginx/nginx.conf

worker_processes auto;
worker_rlimit_nofile 65535;
load_module /usr/local/libexec/nginx/ngx_http_headers_more_filter_module.so;
events {
        multi_accept on;
        worker_connections 65535;
}

http {
        sendfile    on;
        tcp_nopush  on;
        tcp_nodelay on;
        rewrite_log on;

        log_not_found   off;
        server_tokens   off;

        types_hash_max_size 2048;
        client_max_body_size    30M;

        include     mime.types;
        default_type    application/octet-stream;

        access_log  /var/log/nginx/access.log;
        error_log   /var/log/nginx/error.log notice;

        log_format custom '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '"$http_x_forwarded_for" $request_id ';

        ssl_protocols TLSv1.2;
        ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256;
        ssl_prefer_server_ciphers on;



        include /usr/local/etc/nginx/gzip.conf;

        # Includes my virtual domain's configs
        include /usr/local/etc/nginx/conf.d/*.conf;
}

NGINX /usr/local/etc/nginx/conf.d/mywebsite.com.conf

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;

        server_name mywebsite.com;

        root /usr/local/share/www/mywebsite.com;
        index index.php;

    ssl_certificate     /usr/local/etc/letsencrypt/live/mywebsite.com/cert.pem;
    ssl_certificate_key /usr/local/etc/letsencrypt/live/mywebsite.com/privkey.pem;

        access_log  /var/log/nginx/mywebsite.com/access.log;
        error_log   /var/log/nginx/mywebsite.com/error.log notice;

        set $cors '';
        if ($http_origin ~ '^https?://.*\.mywebsite\.com' ) {
                set $cors 'origin_matched';
        }

        # Handles CORS and FASTCGI PHP EXTENSIONLESS
        include /usr/local/etc/nginx/cors-fastcgi.conf;

}

# Redirect all http to https
server {
        listen 80;
        listen [::]:80;
        server_name *.mywebsite.com;
        return 301 https://$host$request_uri;
}

NGINX /usr/local/etc/nginx/cors-fastcgi.conf

    # I ended up using error_page to catch 404 error, 
    # and handle the request using my index.php and returning 200 code
    error_page 404 =200 /index.php?$uri&error_page=404;

    location / {
        set $cors_allowed_methods "GET,POST,PUT,PATCH,DELETE,OPTIONS,HEAD";

        # Preflight requests
        if ($request_method = OPTIONS) {
            set $cors '${cors} & preflight';
        }

        if ($cors = 'origin_matched') {
            add_header 'Access-Control-Allow-Origin' "$http_origin" always;
            add_header 'Access-Control-Allow-Credentials' 'true' always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
            add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;

            # required to be able to read Authorization header in frontend
            add_header 'Access-Control-Expose-Headers' 'Authorization' always;
        }

        if ($cors = 'origin_matched & preflight') {
            add_header 'Access-Control-Allow-Origin' $http_origin always;
            add_header 'Access-Control-Allow-Methods' $cors_allowed_methods always;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            add_header 'Content-Length' 0;
            return 204;
        }
        
        # Example of request: https://www.mywebsite.com/home/lang:en
        # 1) try: /usr/local/share/www/mywebsite.com/home/lang:en
        # 2) try: /usr/local/share/www/mywebsite.com/home/lang:en/ (as a foder/index.php)
        # 3) try: /usr/local/share/www/mywebsite.com/index.php?/home/lang:en (fires my php app to handle the request "/home")
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php-fpm.socket;

        fastcgi_index index.php;

        fastcgi_param SCRIPT_FILENAME $request_filename;

        include fastcgi_params;

        # On error_page redirect, we lost "POST DATA", so used this fastcgi_params to forward POST data to my index.php
        # For compatibility reasons, inside my index.php I populate $_POST with the data coming in $_SERVER[REQUEST_BODY]
        # 
        # if (isset($_SERVER['REQUEST_BODY']) AND $_SERVER['REQUEST_BODY'] > '') {
        #   parse_str($_SERVER['REQUEST_BODY'],$_POST);
        # }
        fastcgi_param CONTENT_TYPE $content_type;
        fastcgi_param CONTENT_LENGTH $content_length;
        fastcgi_param REQUEST_BODY $request_body;
    }

Если у кого-то есть лучшее решение, я принимаю предложения; -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...