为啥 CORS 适用于 API 请求,但不适用于我的 Nginx 配置中的媒体文件(例如 mp4、webm)?
Posted
技术标签:
【中文标题】为啥 CORS 适用于 API 请求,但不适用于我的 Nginx 配置中的媒体文件(例如 mp4、webm)?【英文标题】:Why is CORS working for API requests but not media files (e.g. mp4, webm) on my Nginx config?为什么 CORS 适用于 API 请求,但不适用于我的 Nginx 配置中的媒体文件(例如 mp4、webm)? 【发布时间】:2019-09-28 08:31:14 【问题描述】:我在 Ubuntu 上设置了一个 nginx 服务器,它为两个网站提供服务。一个是提供 API 内容的 Wordpress,另一个是使用 Axios 使用 API 的前端应用程序。
我可以从 API 查询和读取 JSON 内容,并检查响应标头是否与我的 CORS 配置相匹配。但是在 Chrome 上,在从 API 内容读取其 URI 后,应用程序尝试使用的所有媒体文件(.mp4、.webm)的控制台中都出现 CORS 错误。
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.
它可以在 Firefox 上正常运行。
请注意,在 Chrome 的地址栏中粘贴媒体 URI 会按预期显示媒体。也不是视频标签使用crossorigin="anonymous"
。
我做错了什么?
下面是我的 Nginx 配置,以防我遗漏了一些明显的问题。
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;
【问题讨论】:
您确定收到了200 OK
回复吗?
@Brad 我是。奇怪的是,它在针对没有插件的用户配置文件进行测试后现在可以工作,所以我认为这是一个插件问题。
【参考方案1】:
错误响应没有适当的 CORS/Access-Control-*
标头是很常见的。
下次遇到此问题时,请打开浏览器的开发人员工具并检查 HTTP 响应。您可能会看到一些错误状态,而不是 2xx
。
您提到清除 cookie 解决了这个问题。我猜你的应用程序上游有一些错误,清除 cookie 只是解决了该错误情况。因此,CORS 响应按预期重新开始工作。
【讨论】:
【参考方案2】:配置没有问题。
我尝试在没有附加组件的新 Chrome 用户配置文件上成功运行该应用程序。然后我设法在我的主要 Chrome 配置文件上运行它删除我所有的 cookie。我无法解释其背后的基本原理,但它确实有效。在我使用的插件中,我还有罪魁祸首,但我正在关闭这个问题,因为这与 Nginx 无关。
【讨论】:
怀疑是插件问题。可能有一个错误响应,通常不支持 CORS。清除 cookie 可能会清除您在应用程序中遇到的一些错误。 @Brad 这听起来更合理。如果您提供一个而不是后续评论,我会接受您的回答。以上是关于为啥 CORS 适用于 API 请求,但不适用于我的 Nginx 配置中的媒体文件(例如 mp4、webm)?的主要内容,如果未能解决你的问题,请参考以下文章
对外部 API 的 HTTP 请求适用于 .NET,但不适用于 React(CORS 问题)
多个 CORS 适用于 GET 但不适用于 PUT/POST 与飞行前请求 Web api 2
CORS 适用于 chrome 但不适用于 firefox、angularjs
Go Restful API:CORS 配置适用于 React 但不适用于 Angular
使用 CORS 与 LocomotiveJs 一起休息 API。适用于本地机器,但不适用于 Amazon 或 Heroku