跨域原理
1.利用javaScript中的src属性可以实现跨域.
<script type="text/javascript" src="http://manage.jt.com/test.json"></script>
2.定义回调函数.
作用:主要目的获取远程服务器的数据.
function hello(data){
alert(data.name);
}
3.将返回值结果进行特殊的封装.
封装要求:将返回值封装如下 callback(json);
hello({"id":"1","name":"tom"})
jQuery实现跨域访问
编辑页面JS
<script type="text/javascript">
$(function(){
alert("测试访问开始!!!!!")
$.ajax({
url:"http://manage.jt.com/web/testJSONP", //跨域访问
type:"get", //jsonp只能支持get请求
dataType:"jsonp", //dataType表示返回值类型
//jsonp: "callback", //指定参数名称
//jsonpCallback: "hello", //指定回调函数名称
success:function (data){ //data经过jQuery封装返回就是json串
alert(data.id);
alert(data.name);
}
});
})
</script>
编辑WebItemController
@RestController
public class WebJSONPController {
/**
* 该Controller接收的是jt-web服务器发起的请求.进行跨域访问.
*
* url:http://manage.jt.com/web/testJSONP?callback=xxxxxx
* 参数:callback回调函数
* 返回值:特殊格式封装字符串 callback(json数据)
*/
@GetMapping("/web/testJSONP")
public String jsonp(String callback) {
//准备返回值数据
ItemDesc itemDesc = new ItemDesc();
itemDesc.setItemId(10001L)
.setItemDesc("测试跨域访问是否正常!!!!!");
String json = ObjectMapperUtil.toJSON(itemDesc);
return callback +"("+json+")";
}
}
利用工具API实现JSONP请求
/**
* 利用工具API实现JSONP调用
*/
@RequestMapping("/web/testJSONP")
public JSONPObject jsonp(String callback) {
ItemDesc itemDesc = new ItemDesc();
itemDesc.setItemId(10001L)
.setItemDesc("测试跨域访问是否正常!!!!!");
return new JSONPObject(callback, itemDesc);
}
编辑JSONP.html页面
script type="text/javascript">
$(function(){
alert("测试访问开始!!!!!")
$.ajax({
url:"http://manage.jt.com/web/testJSONP", //跨域访问
type:"get", //jsonp只能支持get请求
dataType:"jsonp", //dataType表示返回值类型
//jsonp: "callback", //指定参数名称
//jsonpCallback: "aaa", //指定回调函数名称
success:function (data){ //data经过jQuery封装返回就是json串
alert(data.itemId);
alert(data.itemDesc);
}
});
})
</script>
用户登陆校验
编辑JT-SSO的UserController
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 业务说明:根据用户的参数查询数据库中是否已经存在数据
* url:http://sso.jt.com/user/check/{param}/{type}?callback=xxx
* 参数:param 用户需要校验的参数 /type 用户校验的类型
* 返回值: SysResult JSON数据
* 注意事项: jt-web服务器访问jt-sso 是一个跨域访问形式.
*/
@GetMapping("/check/{param}/{type}")
public JSONPObject checkUser(@PathVariable String param,
@PathVariable Integer type,
String callback) {
//返回标识符 false:表示用户可以使用 true:数据库中以存在
boolean flag = userService.checkUser(param,type);
SysResult sysResult = SysResult.success(flag);
return new JSONPObject(callback, sysResult);
}
}
编辑JT-SSO的UserService
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
//Type为类型,可选参数1 username、2 phone、3 email
//sql:select count(*) from user where
@Override
public boolean checkUser(String param, Integer type) {
//以空间换时间
Map<Integer,String> map = new HashMap<Integer, String>();
map.put(1, "username");
map.put(2, "phone");
map.put(3, "email");
//1.type如何转化为具体的字段 10
String column = map.get(type);
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.eq(column, param);
int count = userMapper.selectCount(queryWrapper);
//存在true ,不存在false
return count>0?true:false;
}
}
页面JS:
$.ajax({
url : "http://sso.jt.com/user/check/"+escape(pin)+"/1?r=" + Math.random(),
dataType : "jsonp", //请求是跨域访问形式
success : function(data) {
checkpin = data.data?"1":"0";
if (!data.data) {
validateSettings.succeed.run(option);
namestate = true;
}else {
validateSettings.error.run(option, "该用户名已占用!");
namestate = false;
}
}
});
编辑全局异常的处理机制,实现跨域异常处理
//@ControllerAdvice //controller的通知
//@ResponseBody //返回值数据是JSON串
@RestControllerAdvice //controller的通知
@Slf4j //动态生成日志
public class SystemExceptionAOP {
//当遇到运行时异常,则执行该方法. 以后写代码时注意异常的范文.
//如果跨域访问形式:一般都会携带参数callback,可以利用callback进行跨域的判断
@ExceptionHandler(Exception.class)
public Object runtimeAOP(Exception exception,HttpServletRequest request) {
String callback = request.getParameter("callback");
//判断是否为jsonp请求 如果是jsonp则返回值需要特殊封装,如果不是则直接返回错误
if(StringUtils.isEmpty(callback)) {
exception.printStackTrace(); //调错方便
log.info("{"+exception.getMessage()+"}");
return SysResult.fail(); //改异常为常规异常
}else {
//进行跨域访问时,应该进行特殊的格式封装
exception.printStackTrace();
log.info("{"+exception.getMessage()+"}");
return new JSONPObject(callback, SysResult.fail());
}
}
}
页面JS修改
$.ajax({
url : "http://sso.jt.com/user/check/"+escape(pin)+"/1?r=" + Math.random(),
dataType : "jsonp", //请求是跨域访问形式
success : function(data) {
checkpin = data.data?"1":"0";
if(data.status==200){
//说明后台业务服务器调用正确
if (!data.data) {
validateSettings.succeed.run(option);
namestate = true;
}else {
validateSettings.error.run(option, "该用户名已占用!");
namestate = false;
}
}else{
validateSettings.error.run(option, "当前服务器正忙,请稍后重试!");
namestate = false;
}
}
});