SpringBoot对jsonp跨域请求的支持
在前端跨域时如果使用post提交会被自动转为get方式,这是因为跨域所使用的数据格式为jsonp。
跨域无效问题解决
关于Vue axios跨域冲突
https://blog.csdn.net/cxz7456/article/details/105907756/
跨域无效问题解决
https://blog.csdn.net/FLGBgo/article/details/123360364
模拟一个跨域访问
修改hosts文件(C:\Windows\System32\drivers\etc\hosts),
添加
127.0.0.1 www.a.com
127.9.0.1 www.b.com
WebMvcConfigurer
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry){
registry.addMapping("/**")
.allowedHeaders("*")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "DELETE", "PUT")
//表示是否允许发送Cookie。默认情况下Cookie不包括在CORS请求中。当设为true时表示服务器明确许可,Cookie可以包含在请求中一起发送给服务器。
.allowCredentials(true)
.maxAge(3600 * 24);
}
接口
@RestController
public class TestController {
@RequestMapping(value="/test")
public String test(HttpServletRequest req)
{
String callback = req.getParameter("callback");
return callback + "({\"name\" : \"zhangSan\"})";
}
}
ajax
Ajax = 异步 JavaScript 和XML。
Ajax是一种用于创建快速动态网页的技术。
通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
Cors是什么
CORS全称为Cross Origin Resource Sharing(跨域资源共享), 每一个页面需要返回一个名为Access-Control-Allow-Origin的http头来允许外域的站点访问,你可以仅仅暴露有限的资源和有限的外域站点访问。
JSONP
jsonp是个非正式的传输协议,jsonp之所以能够绕过浏览器的同源策略是因为除了JavaScript里的Ajax和Fetch请求,其他的请求都不受同源策略的限制——换句话说除了ajax请求,网页中其他的如css,js脚本等资源文件的请求,不会因为跨域而被限制访问。jsonp正是利用了这一点,完成了跨域数据请求。
JSONP的优缺点
优点:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。
缺点:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
<html>
<head>
<title>SpringBoot</title>
<script src="./jquery-3.4.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
function test() {
$.ajax({
type:'get',
url:'http://www.b.com:8080/test',
contentType: 'application/json; charset=UTF-8',
dataType:'jsonp',
jsonp:"callback",
jsonpCallback:"success_jsonpCallback",
success:function (data)
{
$("#showDiv").append("<p>"+data.name +"</p>");
},
error:function (err) {
alert('err!');
}
});
}
</script>
</head>
<body>
<div id="showDiv">
<input type="button" value="test请求" onclick="test()" />
</div>
</body>
</html>
使用jQuery获取跨域数据:
dataType : "jsonp", // 返回的数据类型,设置为JSONP方式
jsonp : 'callback', //jsonp默认值是"callback"
1.jsonp、jsonpCallback jsonp跨域时可以自定义的两个参数
2.jsonp: 回掉函数名的参数名,默认值callback,服务端通过它来获取回调函数名,指定一个查询参数名称来覆盖默认的 jsonp 回调参数名 callback
3.jsonpCallback: 回掉函数名,默认值是以jQuery开头的字符串,这个字符串就是函数调用的名称。
4.指定jsonpCallback时可以将回掉函数写在ajax外面做其他操作,不指定时不能这样做,只能在success里做操作
因为项目是采用分布式架构设计的,各模块之间是相互独立的,而各模块的访问路径又是不同的,所以当跨域请求数据的时候会遇到跨域受限的问题。比如当用户首次访问该网站首页时,首页页面会异步请求后台管理系统加载商品的类目,这是就会出现跨域受限的问题,以前开发时,如果在本模块内,我们是通过ajax异步请求数据的,但Ajax不支持跨域,所以用ajax无法解决跨域请求数据的问题。最后我们使用的是jsonp来解决这个问题的。jsonp通过script标签的src可以跨域请求的特性,加载资源,将加载的资源(通过一个方法名将数据进行包裹)当做是js脚本解析,定义一个回调函数(是怎么实现的?),获取传入的数据。我们使用jsonp是因为Jsonp的兼容性比较好,并且在请求完毕后可以通过callback的方式回传结果。但jsonp有一个缺点是只支持get请求而不支持post等其他类型的http请求。
eval() 函数
eval(data); // 局部变量,eval()函数可以执行参数里的表达式
由于json是以”{}”的方式来开始以及结束的,在JS中,它会被当成一个语句块来处理,所以必须强制性的将它转换成一种表达式。加上圆括号使eval函数在处理JavaScript代码的时候强制将括号内的表达式(expression)转化为对象。
alert(eval(“{}”); // RETURN UNDEFINED
alert(eval(“({})”);// RETURN object[Object]
请求与响应
1访问index.html页面
http://www.a.com:8080/
2点击按钮,调用Ajax
http://www.b.com:8080/test?callback=success_jsonpCallback&_=1566382579338
3返回结果
success_jsonpCallback({“name” : “zhangSan”})
Headers
ajax返回成功却进入了error
接口返回的数据成功,状态是200,但就是没进入success。
原因:后台返回的数据类型不是json的,而我们在ajax里面指定的dataType类型是json的,数据类型不一致就会导致出现进入error的问题。
参考资料
所谓的跨域(Cross-Origin),究竟是什么?
https://blog.csdn.net/u011037503/article/details/78025072
Spring4.1新特性——jsonp
https://blog.csdn.net/z69183787/article/details/52141496
Cross-Origin Read Blocking (CORB)
https://blog.csdn.net/weixin_33743880/article/details/91423231
Access-Control-Allow-Origin,跨域
https://www.cnblogs.com/hofmann/p/10750983.html
从HTTP四种POST 提交数据方式,引申JSON与JSONP区别
https://blog.csdn.net/u012129607/article/details/78949866
ajax Json数据格式交互,上传文件(form-data格式数据)
https://www.cnblogs.com/3sss-ss-s/p/9985294.html
Spring-boot系列(14):jsonp的用法
https://www.cnblogs.com/JQKA/p/11050245.html
Spring Boot 解决跨域问题的 3 种方案
https://mp.weixin.qq.com/s/aC8PC4Z_XuRiBsNfWhRdLg