Исправление заголовка «Access-Control-Allow-Origin» содержит ошибку нескольких значений в NGINX - PullRequest
0 голосов
/ 09 мая 2019

Я настраиваю веб-сайт Wordpress (например, http://api.example.com), чтобы использовать его API с другого статического веб-сайта HTML / JS (например, https://test.example.com).

).

Оба веб-сайта размещены на сервере Nginx, и каждый из них сконфигурирован с помощью файла conf и работает самостоятельно. nginx -t не выдает ошибок, и я имею полный доступ к обоим веб-сайтам, как и ожидалось.

К сожалению, у меня проблемы с CORS. При попытке чтения мультимедийного содержимого (изображений, видео) из api.example.com, test.example.com выдает следующую ошибку в консоли браузера:

Access to XMLHttpRequest at 
'https://api.example.com/wp-json/custom-post/v1/some-data/' 
from origin 'https://test.example.com' has been blocked by CORS policy: 

The 'Access-Control-Allow-Origin' header contains multiple values
'https://test.example.com, https://test.example.com', 
but only one is allowed.

Кроме того, в Chrome за этой ошибкой следует ошибка CORB (Cross-Origin Read Blocking (CORB) blocked cross-origin response https://api.example.com/wp-json with MIME type application/json.).

При проверке заголовка запроса в браузере я заметил избыточные значения для этих свойств:

Access-Control-Allow-Credentials: true, true
Access-Control-Allow-Origin: https://test.example.com, https://test.example.com

Считая, что где-то может быть избыточный Access-Control-Allow-Origin, я искал его в файле nginx.conf и во всех файлах conf в sites-enabled, но безрезультатно. Я также посмотрел исходный код приложения Wordpress, включая используемые плагины, для внедрения этого заголовка. Там не было ничего, чтобы найти.

Наконец, я попытался удалить одну строку в api.example.com.conf, добавив заголовок Access-Control-Allow-Origin - это выдает чистую и простую ошибку No 'Access-Control-Allow-Origin' header is present on the requested resource для мультимедийного содержимого в консоли браузера. Интересно, что это больше не приводит к ошибке CORB для JSON, и test.example.com может читать текстовое содержимое из файлов JSON.

Вот содержимое файла api.example.com.conf:

server {
    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    root /var/www/example.com/backend;
    server_name api.example.com;
    access_log /var/log/nginx/unicorn_access.log;
    error_log /var/log/nginx/unicorn_error.log;

    charset                     utf-8;
    gzip                        off;

    # Set CORS policy
    set $cors_origin            "";
    set $cors_cred              "";
    set $cors_header            "";
    set $cors_method            "";

    if ($http_origin ~ '^https?:\/\/(localhost|test.example\.com)$') {
        set $cors_origin        $http_origin;
        set $cors_cred          true;
        set $cors_header        $http_access_control_request_headers;
        set $cors_method        $http_access_control_request_method;
    }

    add_header Access-Control-Allow-Origin      $cors_origin;
    add_header Access-Control-Allow-Credentials $cors_cred;
    add_header Access-Control-Allow-Headers     $cors_header;
    add_header Access-Control-Allow-Methods     $cors_method;

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

    client_max_body_size        50m;

    # Add trailing slash to */wp-admin requests.
    rewrite /wp-admin$ $scheme://$host$uri/ permanent;

    # Prevents hidden files (beginning with a period) from being served
    location ~ /\. {
        access_log              off;
        log_not_found           off;
        deny                    all;
    }

    # Send 'expires' headers and turn off 404 logging
    location ~* ^.+.(xml|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
        access_log              off;
        log_not_found           off;
        expires                 max;
    }

    # Pass all .php files onto a php-fpm or php-cgi server
    location ~ \.php$ {
        try_files               $uri =404;
        include                 /etc/nginx/fastcgi_params;
        fastcgi_read_timeout    3600s;
        fastcgi_buffer_size     128k;
        fastcgi_buffers         4 128k;
        fastcgi_param           SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass            unix:/run/php/php7.2-fpm.sock;
        fastcgi_index           index.php;
    }

    # Robots
    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    # Restrictions
    location ~* /(?:uploads|files)/.*\.php$ {
        deny all;
    }
}

Я ожидаю, что test.example.com будет использовать любой контент из api.example.com, но я не могу сделать это полностью.

Спасибо за вашу помощь!

1 Ответ

0 голосов
/ 11 мая 2019

Это произошло из-за фильтра rest_send_cors_headers, который перехватывает API REST в rest_pre_serve_request. Он отправлял заголовки CORS с запросами API .

Его можно отключить следующим действием:

add_action('rest_api_init', function() {
    remove_filter('rest_pre_serve_request', 'rest_send_cors_headers');
}, 15);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...