- 前端(layui+jquey)
- 后端springboot
因为前端代码和后端代码分开放在两个不同的项目里,端口号不一致,出现了不同源的情况。
1.什么是源
源[origin]就是协议、域名和端口号。例如:http://www.baidu.com:80这个URL。
2.什么是同源
若地址里面的协议、域名和端口号均相同则属于同源。
3.是否是同源的判断
例如判断下面的URL是否与 http://www.a.com/test/index.html 同源
http://www.a.com/dir/page.html 同源
http://www.child.a.com/test/index.html 不同源,域名不相同
https://www.a.com/test/index.html 不同源,协议不相同
http://www.a.com:8080/test/index.html 不同源,端口号不相同
- 解决方法
1.ajax请求dataType改为jsonp(但是仅限于GET请求,表单提交POST请求就不行了)。
2.Springboot项目使用cors解决跨域问题。 可以在控制器上直接加上@CrossOrigin注解允许什么地址的访问进来。但是鉴于一个项目控制器会很多,而且到达控制器之前会有很多访问过滤验证啥的。这个方式也不理想。所以全局配置肯定是最好的。
控制器添加注解
@CrossOrigin(origins = {"http://localhost:63342", "null"})
全局跨域请求配置
@Configuration
public class MyConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.maxAge(3600)
.allowCredentials(true);
}
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://localhost:63342");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
前端代码
layui.use('form', function(){
var form=layui.form;
form.on('submit(register)',function (data) {
data.field.password=$.md5(data.field.password);
console.log(JSON.stringify(data.field));
console.log(data.field.password);
$.ajax({
type: "POST",
url: "http://localhost:8087/register",
data: JSON.stringify(data.field),
contentType: "application/json;charset=UTF-8",
async: false,
dataType: "json",
xhrFields: { withCredentials: true },
success: function (res) {
alert(res.info);
},
error:function (e) {
alert(e.callback);
}
});
});
});
缺点就是出现了两次请求,一次是options浏览器的探测性请求,一次是有返回值的请求。
- 为什么会出现两次请求呢?
1.请求方式只能是:GET、POST、HEAD
2.HTTP请求头限制这几种字段:Accept、Accept-Language、Content-Language、Content-Type、Last-Event-ID
3.Content-type只能取:application/x-www-form-urlencoded、multipart/form-data、text/plain。
以上三种称为简单请求。而我的Content-type是application/json,明显是属于非简单请求了。非简单请求在正式通信之前,增加一次HTTP请求,称之为预检。浏览器会先询问服务器,当前网页所在域名是否在服务器的许可名单之中,服务器允许之后,浏览器会发出正式的XMLHttpRequest请求,否则会报错。
非简单请求怎么免去预检这个请求,目前还没有解决方案。这样的请求虽然不影响数据,但是看着有点恶心。所以
3.通过docker,nginx来做代理解决请求跨域问题。(这个我还不会,嘿嘿)