在编写SpringMVC接口后,一般通过postman等工具直接访问接口,都可以调用。但如果h5页面通过ajax方式调用非本域名下的接口时,会存在跨域问题。一般时浏览器的安全机制,防止恶意代码。但确实会对项目有一定的影响。通过查阅资料(可以百度出一大堆解决跨域的方法),结合自身项目,得出解决问题的方法。
1.为springboot项目配置出cors,
@Configuration
public class IntercepterConfigurer extends WebMvcConfigurerAdapter {
@Bean
public HandlerInterceptor getFBNIntercepter(){
return new FBNIntercepter();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 多个拦截器组成一个拦截器链
// addPathPatterns 用于添加拦截规则
// excludePathPatterns 用户排除拦截
registry.addInterceptor(getFBNIntercepter()).addPathPatterns("/**");
super.addInterceptors(registry);
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
因为我项目自身有拦截器 @BFNInterceptor ,经过测试,我的拦截器比addCors的优先级高,所以在我拦截器中校验失败返回json时,没有加上cors,所以又在拦截器中单独写了一遍cors
/**
* 跨域问题,拦截器要比Cors要优先级高,所以需要单独设置一下。
* @param request
* @param response
*/
private void addCORS(HttpServletRequest request, HttpServletResponse response){
if (request.getHeader(HttpHeaders.ORIGIN) != null) {
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, HEAD");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
response.addHeader("Access-Control-Max-Age", "3600");
}
}
2.如果不奏效,也可以采用补救方式,在mapping接口上动手脚。
@FBNsecurity(type = ApiType.Query,isSecurity = true,mode = ApiMode.TKP, log=true)
@RequestMapping(value = "/queryOrderDetail", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ApiOperation(value = "查询短信订单详情信息", notes = "短信订单信息",response = TOrderResult.class)
public Torder queryOrderDetail(String accountId,String tradeNo,String billId,String tkp){}
原本这个mapping 是返回Torder对象。ajax在使用jsonp时,会随机生成参数callback,callback必须返回给ajax,这样浏览器才不会解析ajax的result报错。所以修改原来接口返回对象。
@FBNsecurity(type = ApiType.Query,isSecurity = true,mode = ApiMode.TKP, log=true)
@RequestMapping(value = "/queryOrderDetail", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ApiOperation(value = "查询短信订单详情信息", notes = "短信订单信息",response = TOrderResult.class)
public JSONPObject queryOrderDetail(String accountId,String tradeNo,String billId,String tkp,String callback){
if(callback==null){
callback="";
}
JSONPObject引用的是 import com.fasterxml.jackson.databind.util.JSONPObject;
返回值从 return tOrder; 变成return new JSONPObject(callback,tOrder);
PS:由于JSONP的原理其实就是欺骗浏览器,以方式调用接口,解析数据。所以,jsonp的请求方式只能是get方式,如果接口只接受post请求方式,则再做考虑。