如果您的MAGENTO2网站在使用过程中,出现如图示的红色区域提示,那么说明您的网站部分功能存在CROS限制。
在开始前,先了解下什么是CROS?
CORS 代表跨域资源共享,它控制哪些站点可以访问另一个站点的资源。如果您在不同的子域和/或域上运行应用程序并且它们需要相互通信,那么您将需要设置 CORS
我们如何设置 CORS?
需要从正在访问的发送特定的标头HEADER信息。因此,例如,如果您的前端位于一个域上并且它需要访问另一个域上的 API,则您必须在 API 服务器上设置访问标头。
Nginx 配置设置
当一个站点尝试从另一个站点请求访问资源时,它首先会发送一个预请求 preflight request 。这基本上只是询问服务器是否允许该请求,并以 OPTIONS 请求的形式发送。这就是为什么如果您向另一台服务器发送 POST 请求,您也会看到首先发送的 OPTIONS 请求。
因此,我们需要确保当一个 OPTIONS 请求被发送到我们的 Nginx 服务器时,我们以正确的标头进行响应。
如:
if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Allow-Methods' 'POST, GET, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With,X-Cache-Hash' always; ### 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; }
Access-Control-Allow-Origin:允许的域,* 允许所有域。您不能在此处放置多个域(如何限制到多个域将进一步解释)
Access-Control-Allow-Methods:允许 CORS 请求的方法。如果你使用 REST API,你可能也需要 PUT 和 DELETE,因为我使用的是 GraphQL,我只使用 POST、GET 和 OPTIONS。
Access-Control-Allow-Headers:允许的请求头。例如,如果您要发送授权标头而未在此处列出,那么您的请求将被拒绝。
Access-Control-Allow-Credentials:我没有将它包含在我的配置中,但我想解释它的作用。它将允许 cookie 随请求一起发送,例如,如果您需要使用会话 cookie 进行授权。
一般情况下,加这代码到location里面
location / { try_files $uri $uri/ /index.php$is_args$args; }
但是Magento2里面这样子操作不起作用,这是因为M2使用try_files并且如果您将标头设置在此,那么它们将被忽略,它会检查 index.php 文件并在它存在时重定向。所以你需要找到php文件的入口点。
正确的插入
# PHP entry point for main application location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ { set $cors_origin "*"; if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' $cors_origin always; add_header 'Access-Control-Allow-Methods' 'POST, GET, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With,X-Cache-Hash' always; ### 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; } add_header 'Access-Control-Allow-Origin' $cors_origin always; try_files $uri =404; fastcgi_pass fastcgi_backend; fastcgi_buffers 1024 4k; fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off"; fastcgi_param PHP_VALUE "memory_limit=756M \n max_execution_time=18000"; fastcgi_read_timeout 600s; fastcgi_connect_timeout 600s; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
有些时候,我们想对部分域名允许其跨域访问
location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ { set $cors_origin ""; if ($http_origin ~ '^https?://(localhost:8000|mywebsite\.com)$') { set $cors_origin $http_origin; } if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' $cors_origin always; add_header 'Access-Control-Allow-Methods' 'POST, GET, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With,X-Cache-Hash' always; ### 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; } add_header 'Access-Control-Allow-Origin' $cors_origin always; try_files $uri =404; fastcgi_pass fastcgi_backend; fastcgi_buffers 1024 4k; fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off"; fastcgi_param PHP_VALUE "memory_limit=756M \n max_execution_time=18000"; fastcgi_read_timeout 600s; fastcgi_connect_timeout 600s; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
localhost 及mywebsite.com替换成自己的域名。那么此时则只允许部分域名内容跨域。
app/etc/env.php
'x-frame-options' => 'SAMEORIGIN',
允许同源域名
'x-frame-options' => '*',
则为允许全部
'x-frame-options' => 'CROSS-ORIGIN',
限定跨域访问