跨域问题
经常遇到的浏览器跨域报错:“Access to XMLHttpRequest at 'http://different-origin.com/api' from origin 'http://your-origin.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.”本文记录自己开发时遇到的各种跨域报错情况,以及一些解决方法
1.什么是跨域
- 跨域:跨域问题是指在 web 开发中,浏览器出于安全考虑,限制了来自不同源(域名、协议或端口)的网页之间的交互。这种限制是由同源策略引起的,目的是防止恶意网站窃取用户数据或进行其他不安全的操作
- 同源策略:浏览器的同源策略是为了保证用户信息的安全,防止恶意网站窃取数据。同源是指协议、域名、端口完全相同。如果不同源,浏览器就会限制跨域访问资源。
2.自己遇到的场景
- 场景一:通过file:// 协议加载网页,即直接本地打开html文件,但是 JavaScript请求一些第三方资源文件,或者是调用第三方接口获取数据,导致不同源报错。(比如需要临时现场演示,但又没有搭建服务的时候)
- 场景二:本地启动项目后,当前页面域名和后台服务器域名(或直接使用ip)不相同,导致跨域;
- 场景三:前后端开启服务后,后端开放在80,前端开放在81端口,导致跨域;
- 场景四:申请了SSL证书之后,前端采用https协议,后端仍采用http协议导致跨域;
- 场景五:页面中嵌入了来自另一个域名的 iframe,并尝试与 iframe 内的内容进行交互导致跨域。
3.解决方法
-
方法一:最常用的方法就是通过后端服务器配置 CORS 头部,在Springboot中通过实现WebMvcConfigurer接口来全局配置 CORS:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 允许所有路径 .allowedOrigins("http://localhost:3000") // 允许的源 .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的请求方法 .allowedHeaders("*") // 允许的请求头 .allowCredentials(true); // 是否允许发送 Cookie } }
这样通过后端统一处理需要的请求,保证后端与前端同源,通过配置 CORS 头部,以允许特定域名的跨域请求。
-
方法二:如果不想搭建任何后端服务器,想要临时展示简单的前端效果,避免浏览器CORS报错,可以将Chrome浏览器改成非安全模式下访问:
找到Chrome程序,右击打开,找到目标字段,并在目标字段后面加上参数:--disable-web-security --user-data-dir=D:\ChromeData\MyChromeDevUserData
或者在命令行下启动:
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="D:\ChromeData\
-
方法三:Nginx反向代理,这也是很常见的解决方法,即客户端请求nginx服务器,在nginx.conf配置文件中配置server监听客户端的请求,然后把location匹配的路径代理到真实的服务器,服务器处理请求后返回数据,nginx再把数据给客户端返回。
server { listen 80; server_name your.domain.com; location /api/ { proxy_pass http://backend_server/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # CORS 头 add_header 'Access-Control-Allow-Origin' '*'; # 或指定的域名 add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization'; } }
Comments NOTHING