使用Ajax请求SpringBoot接口引发的跨域惨案

最近项目中引入了SpringBoot,目的是做到前后端分离开发。但实际过程中出现了很多问题,其中比较令人头疼的就是跨域问题。

场景再现

创建SpringBoot项目,引入Web、JPA和MySQL

后台接口代码如下:

@RequestMapping(value = "/l", method = RequestMethod.POST)
@ResponseBody
public List add(List list) {
    return list;
}

前台请求代码如下:


前台报错如下:

POST http://localhost:8080/main/l 500 ()

后台报错如下:

org.springframework.beans.BeanInstantiationException: Failed to instantiate [java.util.List]: Specified class is an interface

这里出现的错误原因是因为在接收数组时后台必须使用@RequestBody注解

后台代码调整如下:

@RequestMapping(value = "/l", method = RequestMethod.POST)
@ResponseBody
public List add(@RequestBody List list) {
    return list;
}

再次请求

前台报错如下:

POST http://localhost:8080/main/l 415 ()

状态码415,数据类型有问题。

查看POST的数据

使用Ajax请求SpringBoot接口引发的跨域惨案_第1张图片
image.png

可以看到FormData的数据全部是undefined

前台代码调整如下:


再次请求

前台报错如下:

POST http://localhost:8080/main/l 415 ()
使用Ajax请求SpringBoot接口引发的跨域惨案_第2张图片
image.png

再次查看POST数据,发现数据已经正常了

到这里其实我是懵逼的,因为我找了整整一个上午的资料,完全不知道事出何因。

最后我想到了contentType

于是再次调整前台代码如下:


再次请求

前台报错如下:

OPTIONS http://localhost:8080/main/l net::ERR_ABORTED

查看POST数据

使用Ajax请求SpringBoot接口引发的跨域惨案_第3张图片
image.png

发现请求方法变成了Request Method:OPTIONS

然后我又查了好久,发现是跨域的问题,于是在后台添加跨域配置如下:

package com.semi.demo;

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;

@Configuration
public class CorsConfig {
    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1
        corsConfiguration.addAllowedHeader("*"); // 2
        corsConfiguration.addAllowedMethod("*"); // 3
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); // 4
        return new CorsFilter(source);
    }
}

再次请求


使用Ajax请求SpringBoot接口引发的跨域惨案_第4张图片
image.png
使用Ajax请求SpringBoot接口引发的跨域惨案_第5张图片
image.png

终于成功了。真是内牛满面

总结

使用Ajax请求SpringBoot开发的后台接口时一定要注意:
前台:
1、一定要添加

contentType: "application/json;charset=UTF-8"

2、对于数组,一定要使用

JSON.stringify(list)

进行字符串格式化

后台:
1、一定要在List数据类型前面添加@RequestBody注解
2、一定要进行跨域访问配置

最后

还有一点是关于csrf的,如果遇到此问题只需要添加如下配置类关闭该功能即可。

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
    }
}

喜欢的请关注哦!

你可能感兴趣的:(使用Ajax请求SpringBoot接口引发的跨域惨案)