• 前端(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请求,否则会报错。

非简单请求怎么免去预检这个请求,目前还没有解决方案。这样的请求虽然不影响数据,但是看着有点恶心。所以

java后台设置允许跨域解析_端口号

java后台设置允许跨域解析_端口号_02

3.通过docker,nginx来做代理解决请求跨域问题。(这个我还不会,嘿嘿)