С CORS получилось почти как в анекдоте: "Я долго не понимал, а потом привык".

А сейчас припёрло и срочно пришлось понимать, что это. Не буду повторяться, оставлю три ссылки:

Компьютерная наука наглядно: CORS
Блокировка доступа к данным из-за CORS — повод для радости, а не для грусти. Чтобы прийти к такому же выводу и наконец подружиться с CORS…

Практически классический документ:

Cross-Origin Resource Sharing (CORS) - HTTP | MDN
Cross-Origin Resource Sharing (CORS) — механизм, использующий дополнительные HTTP-заголовки, чтобы дать возможность агенту пользователя получать разрешения на доступ к выбранным ресурсам с сервера на источнике (домене), отличном от того, что сайт использует в данный момент.

Видео, разъясняющее нюансы с точки зрения протокола:

Кроссдоменные запросы (CORS)
Использование Origin-заголовков для возможности из JavaScript осуществлять Ajax-запросы к API на другом домене.

И резюме...

CORS: Cross-Origin Resource Sharing Explained
Cross-origin resource sharing allows a connection to external servers, which is normally forbidden. Does CORS represent a security risk? How does the technology work?

... интересное кратким пересказом по заголовкам:

  • Access-Control-Allow-Origin: Which origin is allowed?
  • Access-Control-Allow-Credentials: Are requests allowed even if the credentials mode is set to include?
  • Access-Control-Allow-Headers: Which headers may be used?
  • Access-Control-Allow-Methods: Which HTTP request methods are allowed?
  • Access-Control-Expose-Headers: Which headers may be displayed?
  • Access-Control-Max-Age: How old may the preflight request be before it expires?
  • Access-Control-Request-Headers: Which HTTP header is specified in the preflight request?
  • Access-Control-Request-Method: Which HTTP method is specified in the preflight request?
  • Origin: What is the source of the request?

Ах да, разумеется, следует не забыть упомянуть

enable cross-origin resource sharing
CORS support site

Содержащий множество примеров серверных конфигов для CORS. Но меня интересует только конфиг для nginx:

#
# Wide-open CORS config for nginx
#
location / {
     if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        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' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
     }
     
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
     }
     
}

Для сайта на PHP есть нюанс: правила надо прописывать не в корневом локейшене, а в location ~ \.php$

Есть подвох: заголовок Access-Control-Allow-Origin работает по принципу "все или один" и принимает либо * , либо конкретное указание домена со схемой (обязательно!) и портом (опционально). И что же нам делать, если мы хотим разрешить хосту отвечать "да" на кросс-доменный запрос из нескольких разных источников?

Есть лайфхак - и для апача (смотрите на SO), и для nginx:

location ~ \.php$ {

if ( $http_origin ~* (https?://(.+\.)?(wintersky|imaginaria)\.(?:ru|me)$) ) {
    set $cors "$http_origin";
}

if ($request_method = 'GET') {
    add_header "Access-Control-Allow-Origin" "$cors";
    ....
}

# аналогично делаем для блоков POST и OPTIONS, если необходимо


}

... и он работает.

P.S. А сколько я пытался разобраться в этом раньше? Нет, пока не упёрся в реальную необходимость внедрения - понимания не возникло. Нет, не отрицаю, полного понимания нет и сейчас, но я хотя бы понял принцип!