SpringBoot对jsonp跨域请求的支持

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

跨域是指在浏览器中,一个网页的脚本试图访问不同源(域、协议、端口)的资源时产生的安全限制。浏览器为了保护用户信息安全,会阻止跨域请求。 解决跨域问题有多种方法,以下是一些常见的解决方案: 1. JSONP(仅支持GET请求):通过在页面中动态创建`<script>`标签,向目标服务器请求数据。服务器返回JSONP格式的数据,浏览器解析并执行回调函数。 2. CORS(跨域资源共享):服务端设置响应头部,允许指定的源进行跨域请求。在Spring Boot中,可以通过添加`@CrossOrigin`注解来实现。 3. 代理服务器:配置一个同源的代理服务器,将浏览器的请求转发到目标服务器,然后将响应返回给浏览器。这种方式需要在服务器端进行配置。 4. WebSocket:使用WebSocket协议进行通信,WebSocket不受同源策略限制。 对于Spring Boot应用解决跨域问题,可以使用CORS方式。在控制器类或方法上添加`@CrossOrigin`注解即可实现跨域请求支持。例如: ```java @RestController @CrossOrigin(origins = "http://example.com") public class MyController { // ... } ``` 上述代码表示允许来自"http://example.com"域的跨域请求。你可以根据实际情况修改`origins`参数,甚至使用`"*"`来允许所有来源的请求。 同时,你也可以在全局配置文件(如`application.properties`或`application.yml`)中添加以下配置来实现全局跨域支持: ```yaml spring: cors: allowed-origins: http://example.com ``` 这样配置后,所有的请求都会允许来自"http://example.com"域的跨域请求
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值