同服务器测试:
1.浏览器的网址信息: http://manage.xx.com/test.html
2.ajax请求的地址信息: http://manage.xx.com/test.json
发现: 请求协议名称://域名:端口号都相同时,请求可以正常进行.
不同服务器测试:
1.浏览器的网址信息: http://www.xx.com/test.html
2.ajax请求的地址信息: http://manage.xx.com/test.json
结论: 域名地址不相同时请求不能正常获取响应的结果.
同源策略
从上述的例子中可以想到:为什么同服务器的请求可以进行,不同服务器的就不行,也就引出了同源策略.
说明:
浏览器在解析ajax时,如果发现请求的协议名称://请求的域名:请求的端口号与网址的地址都相同的时满足同源策略的规定,浏览器可以正确的解析返回值.该访问称之为同域访问.该策略叫做同源策略.
但是如果违反了同源策略中的任意一条,则叫做跨域访问.浏览器出于安全性的考虑.不予解析返回值(请求正常的被处理,但是接收不到返回值).
概括: 浏览器解析ajax时,由于请求违反了同源策略则称之为跨域请求.
跨域访问
跨域访问的常用方式分为两种
JSONP实现跨域
JSONP概念
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。
JSONP实现跨域的原理
第一步:在javaScript中的src属性不受同源策略的约束.可以获取远程服务器数据.
<!--该json一直保存到浏览器中等待调用,但是没有函数名称无法调用 -->
<script type="text/javascript" src="http://manage.jt.com/test.json"></script>
第二步:自定义回调函数 名称任意
/*定义回调函数 */
function hello(data){
alert(data.name);
}
第三步:将返回值结果进行特殊的格式封装 callback(JSON);
hello({"id":"1","name":"tomcat猫"})
JSONP优化实现
1.利用script中的src属性发起请求不方便.不便于程序使用 --> 能否封装为ajax调用方式
2.在请求路径中拼接一个参数一般的key都是约定俗称的 http:xxx/xx?
--> callback=“自定义函数名称”
3.动态的获取callback的参数名称之后进行特殊的格式封装callback(JSON);
JSONP简单示例
1.前端ajax调用
<script type="text/javascript">
$(function(){
alert("测试访问开始!!!!!")
$.ajax({
url:"http://manage.jt.com/web/testJSONP",
type:"get", //jsonp只能支持get请求 src只能是get请求
dataType:"jsonp", //dataType表示返回值类型
//jsonp: "callback", //指定参数名称
//jsonpCallback: "hello", //指定回调函数名称
success:function (data){ //data经过jQuery封装返回就是json串
alert(data.itemId);
alert(data.itemDesc);
}
});
})
</script>
2.后台controller返回数据
@RestController
public class JSONPController {
/**
* 测试跨域访问是否成功
* url地址: http://manage.jt.com/web/testJSONP?callback=jQuery111106536880527642785_1600138715329&_=1600138715330
* 返回值的应该是经过特殊格式封装的数据. callback(JSON)
*/
@RequestMapping("/web/testJSONP")
public String jsonp(String callback){
ItemDesc itemDesc = new ItemDesc();
itemDesc.setItemId(100L).setItemDesc("跨域测试成功!!!!");
String json = ObjectMapperUtil.toJSON(itemDesc);
return callback+"("+json+")";
}
}
3.优化
可以看到现在controller中是通过字符串拼接,拼接为JSONP所需要的特殊格式;
我们可以引入JSONPObject直接返回JSONP所需的格式数据,如下所示:
/**
* 测试跨域访问是否成功
* url地址: http://manage.jt.com/web/testJSONP?callback=jQuery111106536880527642785_1600138715329&_=1600138715330
* 返回值的应该是经过特殊格式封装的数据. callback(JSON)
* JSONPObject参数说明:
* 1.function 回调函数名称
* 2.返回的对象之后可以被转化为JSON
*/
@RequestMapping("/web/testJSONP")
public JSONPObject jsonp(String callback){
ItemDesc itemDesc = new ItemDesc();
itemDesc.setItemId(100L).setItemDesc("API测试!!!");
return new JSONPObject(callback, itemDesc);
}
关于ajax请求时间毫秒的说明
在从前端接受的ajax请求中通常会拼接一串时间毫秒数,由于浏览器内部有缓存机制,所以如果遇到了一个相同的请求地址,浏览器可能会使用之间的结果.(使用缓存),但是有些数据必须要求浏览器重数据库中动态获取数据,为了避免浏览器缓存一般在url最后添加随机数或者时间毫秒数区分url请求.实现该功能.
CORS跨域访问
CORS跨域说明
说明:当下的主流的浏览器默认支持cors跨域的形式,但是需要服务器添加响应的信息.否则浏览器不支持数据的获取.
编辑CORS配置类
说明:在项目的common通用包中添加CORS的配置类
/**
* 实现跨域的方式
* 需要配置服务端程序
* 方法说明:
* 1.addMapping(/**) 允许什么样的请求可以跨域 所有的请求
* 2.allowedOrigins("*")可以允许任意的域名
* 3.allowCredentials(true) 跨域时是否允许携带cookie等参数
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true);
}
}
跨域测试
将返回数据改为json格式,就可以直接进行返回了
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。