I have set up an Nginx server on Ubuntu that serves up two website. One is a Wordpress delivering its API content, the other is a frontend app consuming the API using Axios.
I can query and read the JSON content from the API, and inspecting the response headers matches that of my CORS config. But on Chrome, I'm getting a CORS error in console on all media files (.mp4, .webm) the application is trying to consume after reading their URI from the API content.
Access to video at 'https://api.example.com/wp-content/uploads/2019/05/Seiho-Edited_compress.mp4'
from origin 'https://next.example.com'
has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
It works properly on Firefox.
Note that pasting the media URI in the address bar in Chrome displays the media as expected. Also not that the video tags use crossorigin="anonymous"
.
What am I doing wrong?
Below is my Nginx config, in case there's some glaring issue I missed.
server {
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
root /var/www/example.com/backend;
server_name api.example.com;
access_log /var/log/nginx/unicorn_access.log;
error_log /var/log/nginx/unicorn_error.log;
charset utf-8;
gzip off;
# Set CORS policy
set $cors_origin "";
set $cors_cred "";
set $cors_header "";
set $cors_method "";
if ($http_origin ~ '^https?:\/\/(localhost|next.example\.com)$') {
set $cors_origin $http_origin;
set $cors_cred true;
set $cors_header $http_access_control_request_headers;
set $cors_method $http_access_control_request_method;
}
add_header Access-Control-Allow-Origin $cors_origin;
add_header Access-Control-Allow-Credentials $cors_cred;
add_header Access-Control-Allow-Headers $cors_header;
add_header Access-Control-Allow-Methods $cors_method;
location / {
index index.php index.html;
try_files $uri $uri/ /index.php?$args;
}
client_max_body_size 50m;
# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
# Prevents hidden files (beginning with a period) from being served
location ~ /\. {
access_log off;
log_not_found off;
deny all;
}
# Send 'expires' headers and turn off 404 logging
location ~* ^.+.(xml|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
access_log off;
log_not_found off;
expires max;
}
# Pass all .php files onto a php-fpm or php-cgi server
location ~ \.php$ {
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_read_timeout 3600s;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 128k;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
fastcgi_index index.php;
}
# Robots
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Restrictions
location ~* /(?:uploads|files)/.*\.php$ {
deny all;
}
}
It's pretty common for error responses to not have the appropriate CORS/Access-Control-*
headers.
Next time you run into this, open your browser's developer tools and inspect the HTTP response. It's likely you'll see some error status instead of a 2xx
.
You mentioned that clearing cookies resolved the issue. I'm guessing that there was some error upstream in your application, and that clearing the cookies simply worked around that error condition. Therefore, CORS responses started working again, as expected.