或许会碰到如下问题:
1、跨域
2、不能提交数据
3、每次提交数据产生的sessionId不一致
第一个问题,跨域设置:
参考文档:http://www.imooc.com/article/264678
对某个异步方法设置跨域:
@RestController @RequestMapping("/account") public class AccountController { @CrossOrigin @GetMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ... } @DeleteMapping("/{id}") public void remove(@PathVariable Long id) { // ... } } |
对控制器类设置跨域:
@CrossOrigin(origins = "http://domain2.com", maxAge = 3600) @RestController@RequestMapping("/account") public class AccountController { @GetMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ... } @DeleteMapping("/{id}") public void remove(@PathVariable Long id) { // ... } } |
以及合并跨域设置:
@CrossOrigin(maxAge = 3600) @RestController @RequestMapping("/account") public class AccountController { @CrossOrigin(origins = "http://domain2.com") @GetMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ... } @DeleteMapping("/{id}") public void remove(@PathVariable Long id) { // ... } } |
使用了Spring Security,跨域设置方法:
@EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and()... } } |
全局跨域设置:
@Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter {
@Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**"); } } |
以及:
@Configuration public class MyConfiguration { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**"); } }; } } |
您可以轻松更改任何属性,并仅将此CORS配置应用于特定路径模式:
@Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("http://domain2.com") .allowedMethods("PUT", "DELETE") .allowedHeaders("header1", "header2", "header3") .exposedHeaders("header1", "header2") .allowCredentials(false).maxAge(3600); } |
比如实际中:
@Override public void addCorsMappings(CorsRegistry corsRegistry) { //LOGGER.info("跨域已设置"); corsRegistry.addMapping("/api/**") .allowedOrigins("*") .allowedMethods("*") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } |
如果您使用的是Spring Security,请确保在Spring Security级别启用CORS,以允许它利用Spring MVC级别定义的配置。
基于过滤器的CORS支持
作为上述其他方法的替代方案,Spring Framework还提供了CorsFilter。在这种情况下,您可以在Spring Boot应用程序中声明过滤器,而不是使用@CrossOrigin或WebMvcConfigurer#addCorsMappings(CorsRegistry):
@Configuration public class MyConfiguration { @Bean public FilterRegistrationBean corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("http://domain1.com"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); bean.setOrder(0); return bean; } } |
2、不能提交数据的解决方案:
这个时候多半是因为微信端做Ajax异步提交数据的时候,缺少了header,
{ "Content-Type": "application/x-www-form-urlencoded" } |
/** * 服务端request * @param url 接口链接(除服务器ip和端口之外) * @param method 提交方法(POST或GET) * @param data 提交数据 * @param header 传输格式解析 * @param doSuccess 成功处理方法 * @param doFail 失败处理方法 * @param doComplete 完成处理方法 */ function request(url, method, data, header, doSuccess, doFail, doComplete) { let thatApp = getApp(); var apiUrl = thatApp.globalData.apiUrl; method = method == undefined ? 'GET' : method; header = (header == undefined || header == null) ? thatApp.globalData.requestHeader : header; wx.request({ url: apiUrl + url, data: data, header: header, method: method, success: function(res) { let code = parseInt(res.data.code); console.log('request.response.code', code); /* switch (code) { case 200: // 成功 break; case 401: // 未登录 break; case 411: // 请求参数异常 break; case 555: // 与已有数据重复 break; default: // 默认: 失败 break; } */ if (typeof doSuccess === 'function') { doSuccess(res); } }, fail: function(err) { console.log("request.url=>'"+url+"',error:",err); if (typeof doFail === 'function') { doFail(err); } }, complete: function(e) { if (typeof doComplete === 'function') { doComplete(e); } } }); } |
3、微信端每次提交数据产生的sessionId不一致,解决方案:
登录时产生的sessionId保存到微信端本地存储Storage。
ajax异步请求时,将sessionId放入header中,例子:
// 将登陆成功后获得的sessionId存入本地存储
wx.setStorageSync(app.globalData.sessionIdKey, cookies[0].value); |
// 从本地存储中获取sessionId放入header中
/** * 获得会话Id */ function getSessionId() { let sessionId = wx.getStorageSync(getApp().globalData.sessionIdKey); if (sessionId == null) { sessionId = ''; } return sessionId; }
/** * 获得request-header */ function getRequestHeader() { let header = null; let sessionId = getSessionId(); if (sessionId != '') { header = { "Content-Type": "application/x-www-form-urlencoded", 'Cookie': 'JSESSIONID=' + sessionId } } else { header = { "Content-Type": "application/x-www-form-urlencoded" } } return header; } |