记录一次跨站问题

作者:游鱼思


问题描述

Web应用配置了多个域名,其中一些图片资源的域名与网站访问的域名不一致。在网站中打不开这些图片,但是这些图片的URL单独在浏览器中可以打开。

侦查过程

HTTP状态码是200。表明服务器已成功处理了请求并返回了响应数据。在跨域资源共享(CORS)的上下文中,即使遇到CORS问题,浏览器向服务器的请求也可能收到状态码200的响应。这是因为CORS策略的限制和检查是由浏览器执行的,而不是服务器。服务器可以正常处理请求并返回一个成功的响应,但如果响应中缺少正确的CORS头(如Access-Control-Allow-Origin),浏览器将阻止前端JavaScript代码访问这些响应数据,出于安全考虑。

因此,即使响应状态码为200,仍然可能存在CORS问题,导致资源(如图片、API响应等)在前端页面上无法被正确加载或访问。要诊断CORS问题,可以检查浏览器的控制台(Console)和网络请求日志(Network tab)来查看是否有CORS相关的错误信息,如“Origin is not allowed by Access-Control-Allow-Origin”或“Cross-Origin Request Blocked”。

如果遇到CORS错误,需要确保服务器响应中包含适当的CORS头部,如Access-Control-Allow-Origin。根据你的具体需求,这个头部可以设置为允许特定域的请求,或者使用*来允许来自任何域的请求(尽管后者在生产环境中可能带来安全风险)。

解决方法

Access-Control-Allow-Origin 这个头部用于解决跨源资源共享(CORS)的问题。如果你想在 Nginx 中设置这个头部,你可以将它加在服务配置的 location 块中,这样可以确保这个头部被应用到特定的请求路径上。也可以加在 server 块中,这样它就会应用到该服务器配置下的所有请求上。

只想针对特定路径启用 CORS,你可以将配置放在相应的 location 块中:

# 处理图片资源,添加CORS支持
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
	expires      30d;
	# CORS 设置为宽松,允许任何源访问
	add_header 'Access-Control-Allow-Origin' '*';
	add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
	add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
	# 以下是日志设置,根据需要保留或修改
	# error_log /dev/null;
	access_log /dev/null;
}

这样,只有通过 /api 路径发起的请求才会接收到 Access-Control-Allow-Origin: * 头部。

确保在修改 Nginx 配置后,重新加载或重启 Nginx 以应用更改。你可以使用以下命令之一来完成这个操作:

# 重新加载 Nginx 配置
sudo nginx -s reload

**注意:**将 Access-Control-Allow-Origin 设置为 * 意味着允许任何源访问资源。在生产环境中,建议将其设置为具体的域名,以提高安全性。