Назад | Перейти на главную страницу

По-прежнему получать данные, даже если в Nginx есть проблема с CORS

Я пытаюсь отладить проблему CORS. Вот моя конфигурация, которую я использую http://www.test-cors.org/ чтобы проверить мои правила Nginx. Я получаю сообщение ниже в консоли моего браузера, когда я использую OPTIONS. Но я все равно получил очень странные данные

Failed to load http://www.example.com:8009/testcors: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://www.test-cors.org' is therefore not allowed access.

Я получаю сообщение ниже, если использую метод GET. Я также получаю данные

Failed to load http://www.example.com:8009/testcors: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://www.test-cors.org' is therefore not allowed access.

Вот моя обновленная конфигурация nginx, третье обновление, и я поместил его в новый файл.

  ❯ cat /usr/local/etc/nginx/nginx-mini.conf
  worker_processes  1;
  worker_rlimit_nofile 15000;

  error_log  logs/error.log;
  error_log  logs/error.log  notice;
  error_log  logs/error.log  info;

  events {
   worker_connections  5000;
   accept_mutex off;
  }


  http {
   include       mime.types;
   default_type  application/octet-stream;
   proxy_cookie_path / "/; HTTPOnly; Secure";

   types_hash_max_size 4096;
   access_log off;
   sendfile off;
   sendfile_max_chunk 512k;
   tcp_nopush      off;
   tcp_nodelay      on;
   output_buffers 1 3m;

   open_file_cache          max=10000 inactive=5m;
   open_file_cache_valid    2m;
   open_file_cache_min_uses 1;
   open_file_cache_errors   on;

   gzip on;
   gzip_disable "MSIE [1-6]\.(?!.*SV1)";
   gzip_http_version  1.1;
   gzip_comp_level    5;
   gzip_min_length    256;
   gzip_proxied       any;
   gzip_vary          on;

   gzip_types
     application/atom+xml
     application/javascript
     application/json
     application/rss+xml
     application/vnd.ms-fontobject
     application/x-font-ttf
     application/x-javascript
     application/x-web-app-manifest+json
     application/xhtml+xml
     application/xml
     application/xml+rss
     font/opentype
     image/svg+xml
     image/x-icon
     text/css
     text/javascript
     text/js
     text/plain
     text/x-component
     text/xml;

   # CORS
   map $http_origin $allow_origin {
     default "";
     ~example.com "$http_origin";
   }

   server {
     listen 8009;
     server_name www.example.com;
     access_log /var/log/nginx/access.log;
     error_log /var/log/nginx/error.log debug;

     location /testcors {
        if ($request_method = 'OPTIONS') {
           add_header 'Access-Control-Allow-Origin' $allow_origin;
           add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
           add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
           add_header 'Access-Control-Max-Age' 60;
           add_header 'Content-Type' 'text/plain; charset=utf-8';
           add_header 'Content-Length' 0;
           return 204;
        }
        if ($request_method = 'POST') {
           add_header 'Access-Control-Allow-Origin' $allow_origin;
           add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
           add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
           add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
        }

        if ($request_method = 'GET') {
           add_header 'Access-Control-Allow-Origin' $allow_origin;
           add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
           add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
           add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
           add_header GETMETHOD accessed;
           add_header Content-Type "application/json; charset=utf-8";
        }

       add_header Content-Type "application/json; charset=utf-8";
       return 200 '{"code": 200, "reason": "Testing CORS ..."}';
     }
   }
  }

Я так начал

sudo nginx -c /usr/local/etc/nginx/nginx-mini.conf

пс топор | grep nginx показывает процесс

31528   ??  Ss     0:00.00 nginx: master process nginx -c /usr/local/etc/nginx/nginx-mini.conf
31529   ??  S      0:00.00 nginx: worker process
31787 s003  R+     0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn nginx

netstat показывает порт tcp, связанный с моим nginx

❯ netstat -na|grep 8009
tcp4       0      0  *.8009                 *.*                    LISTEN

IP-адрес правильный

 ❯ ping www.example.com
 PING airborne.gogoinflight.com (127.0.0.1): 56 data bytes
 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.042 ms
 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.067 ms
 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.132 ms

Я убедился, что подключаюсь к собственному локально запущенному серверу nginx с помощью curl

❯ curl http://www.example.com:8009/testcors
{"code": 200, "reason": "Testing CORS ..."}%

И результаты все те же (скриншоты инструментов chrome dev) https://imgur.com/a/PiEks

Проблема в том, что вы не отправляете заголовки CORS в своем location /testcors.

Вы отправляете их только в server блок для любого другого местоположения.

Причина в том, что add_header директивы в блоках нижнего уровня полностью переопределить те, что в блоках более высокого уровня. Итак, поскольку вы использовали add_header в твоем location, вы также должны включить все остальные add_header снова директивы.

Чтобы ваша конфигурация оставалась сухой, вам следует учитывать делая include файл который содержит общие add_header директивы, а затем include это в каждом соответствующем месте конфигурации.

УУХУ !!! Наконец-то я заработал !!! Я узнал, что мы должны указать nginx, что мы хотим сделать, если он не соответствует источнику. Мое первое впечатление от Nginx заключается в том, что он автоматически блокирует домены, если они разные. 99% примеров, которые я нашел, не говорят об этом.

# CORS
map $http_origin $allow_origin {
  default "blocked";
  ~example.com "allowed";
}

map $allow_origin $origin_is_allowed {
  allowed $http_origin;
}

location ~ /getapi/?(?<capture>.*) {
   if ($allow_origin = 'allowed') {
      add_header 'Access-Control-Allow-Origin' "$origin_is_allowed";
      add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
      add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
      add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
      add_header Content-Type "application/json; charset=utf-8";
      proxy_pass http://localhost:7777/api/$capture;
   }
   if ($allow_origin = 'blocked') {
      add_header Content-Type "text/plain";
      return 403 "Your domain is not allowed!";
   }
}

Вот и ошибка test-cors.org :) https://i.imgur.com/CP6oZcZ.png Раньше можно было получать данные, даже если были ошибки cors