跨域
跨域是浏览器拦截返回的响应,防止不同源的数据污染页面。
解决跨域办法
JSONP
通过在script脚本的src后面加入回调函数,回调函数参数即为返回值。
<script>
const callback = res => {
console.log(res);
}
function getHello() {
const script = document.createElement('script');
script.setAttribute("text", "text/javascript");
script.src = 'http://localhost:8080/hello?id=1&jsoncallback=callback';
document.body.append(script);
}
</script>
局限性:只能处理GET请求。
CORS(跨域资源共享)
是一种基于HTTP头的机制,通过服务器标识源,使得跨源数据安全传输。
简单请求
HEAD、GET、POST方法且请求头在以下范围
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:
application/x-www-form-urlencoded、multipart/form-data、text/plain
浏览器在识别到简单请求,自动在请求头加上origin字段。
如果origin不在服务器指定范围内,响应头就没有Access-Control-Allow-Origin字段,就会返回最上面那张图的错误。
但响应的状态码仍是200,我们的接口是调成功了,只是返回的数据被浏览器拦截了。
在后端添加配置
@Configuration
public class CORSConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 匹配所有接口路径
.allowedOrigins("*")
.allowCredentials(false) // 是否允许发送cookie
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.maxAge(3600);
}
}
成功返回的响应头会多出对应的头信息
非简单请求
正式通信前发一个预检请求OPTIONS,带上正式请求的方法和请求头。
服务器检查后若否定预检,浏览器就会报错。
通过后则与简单请求相同。