0
点赞
收藏
分享

微信扫一扫

前后端分离解决跨域问题

村里搬砖的月野兔 2021-09-29 阅读 30
技术博客

什么是跨域

前端跨域

我们前端项目中采用MVVM框架vue.js,2.0以后尤大推荐用axios与后台交互。

功能特性

vue cli脚手架搭建只需要在config目录下的index.js增加changeOrigin的配置即可

dev: {
env: require('./dev.env'),
port: 8080,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api': {
target: 'http://localhost:8004',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}

还需要注意的是,axios 默认是没有携带 cookie 的,如果后台项目是用 session 认证用户信息的话,每次请求的 sessionId 是不一样的。

需要在axios配置中将 withCredentials 设置为 true。

正式环境中,vue.js 代码会被 build 成 html 文件在 nginx 中部署,转发请求到后端服务。

  location /api/ {
proxy_pass http://web-server/;
proxy_connect_timeout 600;
proxy_read_timeout 600;
}

后端跨域

在 spring boot 中有两种跨域方式,在没有启用 spring security 时,直接在请求的controller层注解,类或者方法上都可以,其中 @CrossOrigin 中的2个参数:

  • origins : 允许可访问的域列表
  • maxAge:准备响应前的缓存持续的最大时间(以秒为单位)。
@CrossOrigin(origins = "http://www.baidu.com", maxAge = 3600)
@Api(tags = "数据源", description = "数据源业务类接口服务")
@RestController
@RequestMapping("/dataSource")
public class DataSourceAction {

@Resource
private DataSourceService service;

@CrossOrigin()
@ApiOperation("测试并保存数据源")
@RequestMapping(value = "/saveDataSource", method = RequestMethod.POST)
public void saveDataSource(@RequestParam Map<String, Object> map) throws Exception {
service.testAndSave(map);
}
}

也可以设置成全局

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* @author pilsy
*/

@Configuration
public class MiddlewareConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CorsMiddleware())
.addPathPatterns("/**");
}

public class CorsMiddleware extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler
)
throws Exception {
if (request.getMethod().equals("OPTIONS")) {
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, OPTIONS, DELETE");
response.addHeader("Access-Control-Allow-Headers", "DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,Authorization,If-Modified-Since,Cache-Control,Content-Type");
response.addHeader("Access-Control-Max-Age", "3600");
response.addHeader("charset", "utf-8");
}
return super.preHandle(request, response, handler);
}
}
}

在启用 spring security 后,由 security 管理跨域设置,首先实例化 CorsConfigurationSource

    @Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(AllowedOrigins.getAllowedOrigin());
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "OPTIONS", "PUT", "DELETE"));
configuration.setAllowedHeaders(Arrays.asList("DNT", "X-Mx-ReqToken", "Keep-Alive", "User-Agent", "X-Requested-With", "Authorization", "If-Modified-Since", "Cache-Control", "Content-Type"));
configuration.setAllowCredentials(true);
configuration.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}

再将 CorsConfigurationSource 注册到 security 配置项中

httpSecurity.cors().configurationSource(corsConfigurationSource());
举报

相关推荐

0 条评论