I’m having issues with CORS header Access-Control-Allow-Origin
on GET or POST requests using javascript fetch
Access to fetch at 'https://192.168.1.77/api/contract/list' from origin 'https://192.168.1.77:8090' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
But I can see the Access-Control-Allow-Origin
header is present when inspecting the headers.
Response header
Access-Control-Allow-Headers: DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Accept-Encoding,Accept-Language,Accept,Sec-Fetch-Mode,Sec-Fetch-Site,Sec-GPC,Referer,Pragma,Connection,Host,Content-Length
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Expose-Headers: Content-Length,Content-Range
Cache-Control: no-cache, private
Connection: keep-alive
Content-Type: application/json
Date: Thu, 03 Feb 2022 23:51:05 GMT
Server: nginx/1.21.0
Transfer-Encoding: chunked
WWW-Authenticate: Bearer
X-Debug-Token: 65149f
X-Debug-Token-Link: https://192.168.1.77/_profiler/65149f
X-Powered-By: PHP/8.1.0
X-Robots-Tag: noindex
Request header
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
Cache-Control: no-cache
Connection: keep-alive
Content-Type: application/json
Host: 192.168.1.77
Origin: https://192.168.1.77:8090
Pragma: no-cache
Referer: https://192.168.1.77:8090/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Sec-GPC: 1
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Mobile Safari/537.36
Fetch request
fetch(url, {
mode: 'cors',
headers: {
'Content-Type': 'application/json'
}
}
);
Nginx config
location ~ ^/index.php(/|$) {
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' 'https://192.168.1.77:8090';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Accept-Encoding,Accept-Language,Accept,Sec-Fetch-Mode,Sec-Fetch-Site,Sec-GPC,Referer,Pragma,Connection,Host,Content-Length' always;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Vary' 'origin';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' 'https://192.168.1.77:8090';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Accept-Encoding,Accept-Language,Accept,Sec-Fetch-Mode,Sec-Fetch-Site,Sec-GPC,Referer,Pragma,Connection,Host,Content-Length' always;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Vary' 'origin';
}
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://192.168.1.77:8090';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Accept-Encoding,Accept-Language,Accept,Sec-Fetch-Mode,Sec-Fetch-Site,Sec-GPC,Referer,Pragma,Connection,Host,Content-Length' always;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Vary' 'origin';
# 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;
}
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_pass php-upstream;
fastcgi_split_path_info ^(.+.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}
What am I missing ?
2
Answers
From the server side, from your API that is, add the following line to have access from outside the server:
You wrote, "I can see the
Access-Control-Allow-Origin
header…", but in the code you pasted, I do not see it. I’m looking at the Response headers you pasted above.(For clarity:
Access-Control-Allow-Origin
is its own key in the headers. It’s not bundled intoAccess-Control-Allow-Headers
or anything else.)You might need to return a response from the api something like this:
Aside:
fetch
hasmode: 'cors'
by default, so no need to include in your request code.Did you mean to fetch from
https://192.168.1.77:8090/api/contract/list
instead ofhttps://192.168.1.77/api/contract/list
?Perhaps the different/missing port number is causing the cross-origin issue?