Проблема CORS с Angularjs + Spring-boot + nginx

Вот уже пару дней я выдергиваю волосы. У меня есть бэкэнд-сервер, использующий Spring-boot с Rest API

Этот сервер вызывается из внешнего интерфейса с использованием AngularJS, который также обрабатывается Nginx.

Все работает локально. Всякий раз, когда я пытаюсь сделать запрос от внешнего интерфейса к серверной части, я получаю следующую ошибку:

Проблема CORS с Angularjs + Spring-boot + nginx

Я знаю, что вы думаете: просто добавьте add_header 'Access-Control-Allow-Origin' 'http: // [MY_IP]'; в ваш файл nginx.conf на бэкэнде, и все будет работать, как здесь. или здесь.

Но это не так. Я все перепробовал, переместил в разные места, поставил '*' вместо адреса, включил и отключил SSL ... Единственное, что работает, - это когда я вручную отключаю ограничения Cross-Origin в браузере. И самое приятное то, что когда я снимаю эти ограничения, я вижу, что заголовок Access-Control-Allow-Origin установлен на http: // [MY_IP] в консоли отладки моего браузера!

Есть идеи, что может пойти не так?

Вот мой файл nginx.conf:

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    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;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

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

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    include /etc/nginx/sites-enabled/*;
}

Вот мой файл /etc/nginx/sites-enabled/default.conf:

upstream backend_api {
    server 10.34.18.2:8080;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name _;

    root /var/www/html/;
    index index.html;

    client_max_body_size 5M;

    location /todos {
        access_log  /var/log/nginx/todos.backend.access.log;
        error_log   /var/log/nginx/todos.backend.error.log;

        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_pass http://backend_api;
    }

    location / {
        access_log  /var/log/nginx/todos.frontend.access.log;
        error_log   /var/log/nginx/todos.frontend.error.log;

        try_files $uri $uri/ =404;
    }

}

Создаю символическую ссылку:

ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/

Вы пробовали изменить URL-адрес в коде запроса на http://10.34.18.2:8080/docs/ (с косой чертой в конце)? Дело в том, что снимок экрана i.stack.imgur.com/eFKpE.png не показывает никаких ошибок - вместо этого на снимке экрана просто показан успешный запрос к http://10.34.18.2:8080/docs и сервер, отвечающий (без ошибок) перенаправлением 302 на http://10.34.18.2:8080/docs/. Таким образом, сервер просто говорит: «Вы забыли добавить косую черту в конце URL-адреса запроса».. Если при входе в консоль инструментов разработчика возникает другая ошибка, добавьте ее в вопрос.

sideshowbarker 16.12.2018 23:25

Если конечная точка API, к которой ваш код обращается, является сервером Spring Boot, вы понимаете, что это сервер, который должен отправить обратно Access-Control-Allow-Origin, верно? Поэтому, если настоящая проблема заключается в том, что браузер регистрирует сообщение «отсутствует заголовок Access-Control-Allow-Origin» в консоли разработчика, исправление состоит в том, чтобы настроить сервер Spring Boot для отправки этого заголовка обратно. Если ваш запрос не идет на сервер nginx, тогда ваша конфигурация nginx не имеет значения (и в любом случае фрагменты конфигурации nginx в вопросе не показывают, что заголовок Access-Control-Allow-Origin нигде установлен ...)

sideshowbarker 16.12.2018 23:43
Знаете ли вы, что директивы являются одной из самых мощных и универсальных функций Angular?
Знаете ли вы, что директивы являются одной из самых мощных и универсальных функций Angular?
Директивы позволяют расширять HTML новыми элементами и атрибутами и даже создавать собственные структурные директивы для манипулирования DOM. С...
Разница между Angular и React
Разница между Angular и React
React и AngularJS - это два самых популярных фреймворка для веб-разработки. Оба фреймворка имеют свои уникальные особенности и преимущества, которые...
0
2
1 886
1

Ответы 1

Я не уверен, что это заставит cors работать, но это может помочь приблизиться к решению:

Access-Control-Allow-Origin: http://[MY_IP] - не единственный заголовок, о котором вам нужно позаботиться.

Поскольку Content-Type - это application/json, а также вы не используете непростые заголовки, вам также нужно будет дать конкретное разрешение для заголовка Content-Type, то же самое с Accept-Encoding и DNT.

Access-Control-Allow-Headers: Content-Type, Accept-Encoding, DNT

Я не уверен насчет этого для этого конкретного GET, но в любом случае также допустимые методы:

Access-Control-Allow-Methods: GET

И если вы отправляете файлы cookie, заголовок авторизации или клиентские сертификаты для аутентификации:

Access-Control-Allow-Credentials: true

Я не думаю, что это ваш текущий случай, но обратите внимание, что возврат Access-Control-Allow-Credentials: true и слепая репликация полученного Origin в ответе Access-Control-Allow-Origin позволяет любому сайту получить доступ к вашему серверу, выдавая себя за владельца учетных данных.

И на всякий случай, если вы соблазнитесь, ACAO: * с ACAC: true не будет работать в соответствии со спецификацией.

Возможно, вам также придется позаботиться о методе OPTIONS, вызываемом во время предварительной проверки cors, который должен соответствовать тому, что будет отвечать фактический вызов.

И помните, что отказ от возврата одного из этих заголовков - это способ отрицать это.

Ссылка: CORS - MDN

Другие вопросы по теме