前端 加上dataType: "jsonp"
$.ajax({
url: "http://localhost:8080/test/get1",
//返回内容Content-Type:application/javaScript 而不是默认的json
//请求类型:type:script 而不是XHR
/*jsonp就是动态创建script标签
* 它指望服务端返回是js代码*/
dataType: "jsonp",//这样发出去的请求是script不再是XHR了 所以会得到浏览器的允许
jsonp: "callback2",//自己命名的 和后台一样就行 不写默认叫callback
// cache: true,//请求可以被缓存 (默认是不可以 请求上还会带一个随机数参数防止缓存
success: function (json) {/*这样返回json当成js代码来解析 当然会报错
必须改服务端代码 添加JsonpAdvice.java */
result = json;
}
});
后端也要改,增加一个Advice
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice;
/**
* 服务端配合jsonp 允许跨域
*/
//用于jsonp 返回js代码
// jsonp弊端
// 1.只支持get 即使ajax写了要post 也是get
// 2.服务端不是自己的 不能改 了
//3.XHR请求被改成script了 前者的特性用不到
@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
public JsonpAdvice() {
//jsonp请求会自动在请求后面加 ?callback2=jQuery1113021322045250311494_1533960114852
//jQuery1113021322045250311494_1533960114852就是回调函数名
//服务端看到这个就知道是jsonp请求 返回的是"callback2(原来的json);"这样一段js脚本 让前端运行
super("callback2");//这个命名自己定,和前端一致就行
}
}
可以看到 加了dataType: "jsonp"
以后,返回值类型变成
Content-Type:application/javaScript 而不是默认的json,
请求类型也变成了script,不是xhr了
JSONP.png
确实返回了js.png
下图↓是普通的 之前的,没加dataType: "jsonp"
的返回类型 json 对比一下
原来的.png
原理
这是一个非官方的协议,协议就是约定,
约定:
前端传 http://localhost:8080/test/get1?callback2=jQuery111309357254671860198_1537368249736
后端就返回这样的js函数调用
jQuery111309357254671860198_1537368249736(原来的json数据)
前端就能拿到这个json对象
前端顺利拿到json.png
callback
可以自定义成其他名字 ,比如我这里就改名为了callback2
前端是通过动态创建一个script脚本发出的这个
http://localhost:8080/test/get1?callback2=jQuery111309357254671860198_1537368249736
请求的
发出请求后这个脚本就销毁了
可以去jquery里面打断点去未销毁前看dom,<head>
里面被加了一个脚本
<head>
<script
async=""
src="http://localhost:8080/test/get1?callback2=jQuery111309357254671860198_1537368249736">
</script>
<meta charset="UTF-8">
弊端
- 只支持get 即使ajax写了要post 也是get,因为script请求只能是get
- 服务端不是自己的 不能改 了
- XHR请求被改成script了 前者的特性(异步,各种事件)用不到
\