Чому мій API працює в Postman, але ламається в браузері?
Бо CORS застосовують браузери і більше ніхто. Postman, curl, Insomnia і ваш власний бекенд не застосовують жодних правил CORS, тож отримують відповідь із будь-якими заголовками. Сервер зазвичай поводиться однаково в обох випадках. Різниця цілком у тому, що робить з відповіддю той, хто викликає, а браузер відмовляється передати її вашому JavaScript, доки відповідь не скаже, що це джерело може її прочитати.
Що таке запит preflight?
Це запит OPTIONS, який браузер надсилає перед справжнім, щоб спитати, чи дозволено справжній. Він несе Origin, Access-Control-Request-Method і, за потреби, Access-Control-Request-Headers. Якщо відповідь не дозволяє запит, справжній не надсилається взагалі, тож ваша кінцева точка його ніколи не бачить, а в журналах сервера нічого немає. Preflight роблять лише для запитів, які не є простими.
Чому application/json спричиняє preflight, а text/plain ні?
Content-Type є в безпечному списку CORS лише для application/x-www-form-urlencoded, multipart/form-data і text/plain. Саме ці три і жодного більше. Тіло JSON виводить запит за межі безпечного списку, тож браузер оголошує його наперед. Саме тому додавання API JSON до наявної сторінки раптом породжує запит OPTIONS, якого ніхто не писав.
Чому не можна використати Access-Control-Allow-Origin: * з обліковими даними?
Бо відповідь, прив'язана до користувача, який увійшов у систему, не повинна бути доступною для читання кожному сайту, який цей користувач відвідує. Коли запит надсилає файли cookie або автентифікацію HTTP, сервер має назвати джерело, якому він довіряє, а браузер відхиляє зірочку одразу, навіть поруч із Access-Control-Allow-Credentials: true. Те саме стосується зірочки в Allow-Methods, Allow-Headers і Expose-Headers: для запиту з обліковими даними кожну з них читають як буквальну назву заголовка, а не як символ підстановки.
Чи захищає CORS мій API?
Ні. CORS вирішує, які джерела можуть прочитати відповідь усередині браузера. Це не автентифікація, він не надає жодних дозволів і не спиняє міжсайтову підробку запитів, бо атаці CSRF не потрібно читати відповідь. Будь-який клієнт, що не є браузером, повністю його ігнорує. Залиште автентифікацію, перевірки авторизації і токени CSRF рівно такими, якими вони є.
Звідки надходять ці запити і що зберігається?
З серверів POLPROG до вказаної вами кінцевої точки, бо браузер не може виконати таку діагностику сам щодо себе: саме CORS йому б це заблокував. Надсилаються лише заголовки, потрібні для аналізу, жоден ваш файл cookie не пересилається, тіло запиту не надсилається ніколи, а тіла відповідей відкидаються. Після того, як звіт дійде до вас, нічого не зберігається, а значення чутливих заголовків, як-от Authorization, ніколи не показуються і не експортуються.