У нижченаведеному дослідженні як API я використовую http://example.com замість http: // myApiUrl / login з вашого запитання, тому що цей перший працює.
Я припускаю, що ваша сторінка знаходиться на http: //my-site.local: 8088 .
Причина, чому ви бачите різні результати, полягає в тому, що листоноша:
- встановити заголовок
Host=example.com
(ваш API)
- НЕ встановити заголовок
Origin
Це подібно до способу надсилання запитів у веб-переглядачах, коли сайт і API мають однаковий домен (браузери також встановлюють елемент заголовка Referer=http://my-site.local:8088
, однак я його не бачу в Postman). Якщо Origin
заголовок не встановлений, зазвичай сервери дозволяють такі запити за замовчуванням.
Це стандартний спосіб, як поштальон надсилає запити. Але браузер надсилає запити по-різному, коли на вашому веб-сайті та API є різні домени , і тоді виникає CORS і браузер автоматично:
- встановлює заголовок
Host=example.com
(ваш як API)
- встановлює заголовок
Origin=http://my-site.local:8088
(ваш сайт)
(Заголовок Referer
має те саме значення, що і Origin
). А тепер на вкладці " Консолі та мережі Chrome" ви побачите:
Коли у вас Host != Origin
це CORS, і коли сервер виявляє такий запит, він зазвичай блокує його за замовчуванням .
Origin=null
встановлюється, коли ви відкриваєте вміст HTML з локального каталогу, і він надсилає запит. Така ж ситуація, коли ви надсилаєте запит всередині <iframe>
, як, наприклад, у фрагменті нижче (але тут Host
заголовок взагалі не встановлений) - загалом, скрізь, де специфікація HTML говорить про непрозоре походження, ви можете перекласти це на Origin=null
. Більше інформації про це ви можете знайти тут .
fetch('http://example.com/api', {method: 'POST'});
Look on chrome-console > network tab
Якщо ви не використовуєте простий запит CORS, зазвичай браузер автоматично надсилає запит OPTIONS перед тим, як надсилати основний запит - більше інформації тут . Розріз нижче показаний:
fetch('http://example.com/api', {
method: 'POST',
headers: { 'Content-Type': 'application/json'}
});
Look in chrome-console -> network tab to 'api' request.
This is the OPTIONS request (the server does not allow sending a POST request)
Ви можете змінити конфігурацію вашого сервера, щоб дозволити запити CORS.
Ось приклад конфігурації, яка вмикає CORS на nginx (файл nginx.conf) - будьте дуже обережні з налаштуваннями always/"$http_origin"
для nginx та "*"
Apache - це розблокує CORS з будь-якого домену.
location ~ ^/index\.php(/|$) {
...
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' "$http_origin"; # DO NOT remove THIS LINES (doubled with outside 'if' above)
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'My-First-Header,My-Second-Header,Authorization,Content-Type,Accept,Origin';
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain charset=UTF-8';
return 204;
}
}
Ось приклад конфігурації, яка вмикає CORS на Apache (.htaccess файл)
# ------------------------------------------------------------------------------
# | Cross-domain Ajax requests |
# ------------------------------------------------------------------------------
# Enable cross-origin Ajax requests.
# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
# http://enable-cors.org/
# <IfModule mod_headers.c>
# Header set Access-Control-Allow-Origin "*"
# </IfModule>
# Header set Header set Access-Control-Allow-Origin "*"
# Header always set Access-Control-Allow-Credentials "true"
Access-Control-Allow-Origin "http://your-page.com:80"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Allow-Headers "My-First-Header,My-Second-Header,Authorization, content-type, csrf-token"