案例1:
页面网址:http://manage.jt.com:80/test.html
ajax请求: http://manage.jt.com:80/test.json
结论: 当请求协议://域名:port端口号都相同时 访问正常的.
案例2:
页面网址:http://www.jt.com:80/test.html
ajax请求:http://manage.jt.com:80/test.json
结论: 当浏览器的地址与ajax地址不同时,请求不能正常执行.
说明:浏览器在发起AJAX请求时,必须遵守同源策略的规定.否则数据无法正常解析.
策略说明:发起请求时,必须满足 协议://域名:端口都相同(和当前页面对比)时.满足同源策略要求.浏览器可以正确的发起请求,并且解析结果.,
但是如果上述的三项中有一项不同,则表示跨域访问.浏览器不予解析返回值结果.
例题: 问http://manage.jt.com/test.html 和http://localhost:8091/test.json 能否通信?
答案: 不能通信
1)域名不一致
2)端口不同
定义: 当浏览器解析ajax时,ajax发起请求的地址如果与当前页面所在的地址违反同源策略时,则称之为跨域(请求)
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的
1).利用javascript中的src属性实现跨域
<script type="text/javascript" src="http://manage.jt.com/test.json"></script>
2).自定义回调函数 function callback(){}
function hello(data){
alert(data.name);
}
3).将返回值结果 进行特殊的格式封装 callback(JSON数据)
hello({"id":"1","name":"tomcat猫"})
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSONP测试</title>
<script type="text/javascript" src="http://manage.jt.com/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
alert("测试访问开始!!!!!")
//网页位置: www.jt.com/JSONP.html
$.ajax({
url:"http://manage.jt.com/web/testJSONP",
type:"get", //jsonp只能支持get请求 不支持post,因为src支持get
dataType:"jsonp", //dataType表示返回值类型 如果是跨域访问,则必须添加jsonp
//jsonp: "callback", //指定参数名称
//jsonpCallback: "hello", //指定回调函数名称
success:function (data){ //data经过jQuery封装返回就是json串
alert(data.id);
alert(data.name);
//转化为字符串使用
//var obj = eval("("+data+")");
//alert(obj.name);
}
});
})
</script>
</head>
<body>
<h1>JSON跨域请求测试</h1>
</body>
</html>
说明: 在jt-manage中添加JSONPController.实现跨域访问
@RestController
public class JSONPController {
/**
* url:http://manage.jt.com/web/testJSONP?callback=jQuery111107990405330439474_1595323762313&_=1595323762314
* @return JSONPObject 专门负责封装JSONP的返回值结果的.
* 注意事项: 返回值结果必须通过特殊的格式封装 callback(JSON数据)
*/
@RequestMapping("/web/testJSONP")
public JSONPObject jsonp(String callback) {
//准备返回数据
User user = new User();
user.setId(100L).setPassword("我是密码");
return new JSONPObject(callback, user);
}
}
说明:当下的主流的浏览器天生都支持跨域,通过添加请求头信息,将源地址进行标识,之后发往后端服务器.
关键点: 跨域请求由浏览器和服务器共同完成,.要求双方都必须同意跨域才行. 但是默认的条件下服务器端是不允许跨域的.所以必须经过配置才行.
说明:在jt-common中添加跨域配置
//类似于web项目中使用的web.xml配置文件
@Configuration
public class CorsConfig implements WebMvcConfigurer{
/**
* 配置后端服务器可以跨域的清单
* 参数说明: addMapping:什么样的请求可以进行跨域 /web/** /aaa/b/c/e/d/d/d
* /* 匹配一级目录
* /** 匹配多级目录 使用最多
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*") //配置源 通配
.allowedMethods("GET","POST","PUT","DELETE","HEAD") //允许的请求方式
.allowCredentials(true) //是否允许携带cookie
.maxAge(1800); //允许跨域的持续时间
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试JSON跨域问题</title>
<script type="text/javascript" src="http://manage.jt.com/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript">
/*$(){}结构必然是jQuery函数类库导入后才能正确执行*/
$(function(){ //正常
alert("我要进行cors的跨域了!!!!"); //正常
//利用jQuery发起AJAX请求
$.get("http://manage.jt.com/web/testCors",function(data){
alert(data.id);
alert(data.password);
})
})
</script>
</head>
<body>
<h1>JSON跨域请求测试</h1>
</body>
</html>
@RestController
public class CorsController {
@RequestMapping("/web/testCors")
public User testUser() {
System.out.println("我执行了业务操作!!!");
return new User().setId(100L).setPassword("我是cors的返回值!!!!");
}
}