跨域问题是指在前端Web开发中,不同源的网页之间无法相互访问或通信的问题。产生跨域问题的原因是由于浏览器的同源策略(Same Origin Policy)所导致的。
同源策略是浏览器的一种安全机制,限制了来自不同源(域名、端口、协议)的文档或脚本之间的交互,如 XMLHttpRequest 或 Fetch 请求、跨窗口和跨框架访问文档或脚本等。同源策略的目的是保护用户的隐私和安全,防止恶意代码窃取用户的信息或篡改网页内容。
举个例子,假设有两个网站 A 和 B,它们的 URL 如下:
A网站:https://www.a.com
B网站:https://www.b.com
由于 A 和 B 的协议(http/https)、主机名(www.a.com 和 www.b.com)和端口号(默认为80)都不相同,因此它们被认为是不同的源。如果在A网站中使用 JavaScript 代码尝试获取B网站的数据,就会受到同源策略的限制,无法成功获取数据。
要解决跨域问题,一般有以下几种方式:
JSONP(JSON with Padding)跨域请求:通过在页面上添加一个 标签,并指定其 src 属性为跨域请求的 URL,服务器返回的数据会被当做 JavaScript 代码执行,从而实现跨域数据的获取。不过 JSONP 只支持 GET 请求,且无法处理 POST 请求等场景。
CORS(Cross-Origin Resource Sharing)跨域请求:通过在服务端设置响应头部的 Access-Control-Allow-* 字段,授权指定源可以访问资源,从而实现跨域数据的获取。CORS 请求支持 GET 和 POST 等任意请求方式。
代理跨域请求:通过在自己的服务器上建立代理服务器,将前端请求发送给代理服务器,再由代理服务器向目标服务器发送请求,并返回目标服务器的响应。通常用于请求第三方 API 数据等场景。
解决方案:
前端与后端都会有解决方案
但前端往往不能根本解决问题!
因此如何你的后端同事让作为前端工程师的你来解决问题,请一定来打他!
后端较为主流的解决方案
就在在config中进行配置
package com.fanchen.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 跨域请求配置* 解决跨域问题的配置**/
@Configuration
public class CorsConfig implements WebMvcConfigurer {@Beanpublic CorsFilter corsFilter(){// 1. 添加cors配置信息CorsConfiguration config = new CorsConfiguration();// Response Headers里面的Access-Control-Allow-Origin: http://localhost:8080config.addAllowedOrigin("http://localhost:8081");// 其实不建议使用*,允许所有跨域//config.addAllowedOrigin("*");// 设置是否发送cookie信息,在前端也可以设置axios.defaults.withCredentials = true;表示发送Cookie,// 跨域请求要想带上cookie,必须要请求属性withCredentials=true,这是浏览器的同源策略导致的问题:不允许JS访问跨域的Cookie/*** withCredentials前后端都要设置,后端是setAllowCredentials来设置* 如果后端设置为false而前端设置为true,前端带cookie就会报错* 如果后端为true,前端为false,那么后端拿不到前端的cookie,cookie数组为null* 前后端都设置withCredentials为true,表示允许前端传递cookie到后端。* 前后端都为false,前端不会传递cookie到服务端,后端也不接受cookie*/// Response Headers里面的Access-Control-Allow-Credentials: trueconfig.setAllowCredentials(false);// 设置允许请求的方式,比如get、post、put、delete,*表示全部// Response Headers里面的Access-Control-Allow-Methods属性config.addAllowedMethod("*");// 设置允许的header// Response Headers里面的Access-Control-Allow-Headers属性,这里是Access-Control-Allow-Headers: content-type, headeruserid, headerusertokenconfig.addAllowedHeader("*");// Response Headers里面的Access-Control-Max-Age:3600// 表示下回同一个接口post请求,在3600s之内不会发送options请求,不管post请求成功还是失败,3600s之内不会再发送options请求// 如果不设置这个,那么每次post请求之前必定有options请求// 当前跨域请求最大有效时长。这里默认1天long maxAge = 24 * 60 * 60;config.setMaxAge(maxAge);config.addExposedHeader("Authorization");// 2. 为url添加映射路径UrlBasedCorsConfigurationSource corsSource = new UrlBasedCorsConfigurationSource();// /**表示该config适用于所有路由corsSource.registerCorsConfiguration("/**", config);// 3. 返回重新定义好的corsSourcereturn new CorsFilter(corsSource);}
}