一、跨域问题
- 同源策略(SOP):
访问浏览器的URL地址和发送XHR请求的URL地址必须满足三个一致:协议一致、域名一致、端口一致
同源策略规定:如果访问浏览器的URL地址和发送XHR请求的URL地址不同源,则无法发送XHR请求(ajax请求),会产生跨域问题。 - 跨域问题:是浏览器的安全级别造成的。
- 模拟跨域:在本地产生两个服务器:
(1)客户端通过Hbuild而访问。
(2)服务器通过自身的服务器访问。
二、JSONP技术
通过浏览器发送的请求被称为“HTTP请求”,其中包括资源请求、表单请求、XHR请求。
- 通过不向服务器发送XHR请求的方法来解决跨域问题。此时,JSONP要求向服务器发送一个资源请求。
- 什么是资源请求:通过HTML标记向服务器请求的外部文件就是资源请求。
例:<script></script>
、<img></img>
、<audio></audio>
、<video></video>
等 - 哪些标记可以帮助我们将后台文件(.jsp、.php、.axpx)的请求变为资源请求?
<script type="text/javascript" src="http://localhost:8080/ajax/index.jsp"></script>
1、例一
利用资源请求方式向服务器申请一个空的jsp文件。
<script src="http://localhost:8080/ajax/index.jsp"></script>
通过开发人员工具的newwork选项卡,可以看出此时对jsp文件的请求已经无法通过XHR筛选出来,同时可以通过js筛选出来。
此时说明jsp文件是一个资源请求。
2、例二
向后台的jsp文件书写一些JavaScript代码,看看是否能够被响应
可以响应
3、例三
如果在前端写一个function,后台能不能调用呢?
//前端代码:
function hello(a){
alert(a);
}
//后台代码:
<%
String abc="你好,我是服务器返回的响应";
%>
hello("<%=abc%>");
可以调用
结论:通过资源请求浏览器可以得到服务器的响应文本
4、如何通过资源请求向服务器传递参数?
例四:
向服务器传递两个参数,并返回两个参数相加之后的结果。
可以将向服务器传递的参数书写在资源请求的地址末尾。
<script src="http://localhost:8080/ajax/index.jsp?m=25&n=30"></script>
//后台代码
<%
int m=Integer.parseInt(request.getParameter("m"));
int n=Integer.parseInt(request.getParameter("n"));
int result=m+n;
%>
hello("<%=result%>");
5、
人们认为,按照如下的格式书写JSONP代码更加符合编程的思想:
问题:前端定义的函数后台要调用,那么函数名前后台要商量好。
解决:将前端的函数名也作为一个普通参数传递给服务器,参数名为cb或callback。
前端代码:
后台代码:
三、原生JavaScript下的JSONP技术应用
//让后台调用下列函数
var result;
function getData(res) {
result = res;
}
btn.onclick = function(event) {
event.preventDefault();
//获取文本框中的数据
var exno = document.forms[0].exno;
var exname = document.forms[0].exname;
//动态创建对服务器文件的资源请求
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://localhost:8080/ajax/checkGrade.jsp?cb=getData&exno=" + exno.value + "&exname=" + exname.value;
document.body.appendChild(script);
//对后台响应的文本进行分析
script.onload = function() {
if(result.code === "1") {
alert("您的成绩:" + result.grade);
} else {
alert("没有查询到您的考生成绩");
}
}
}
四、jQuery下的JSONP技术应用
$("#btn").on("click", function(event) {
event.preventDefault();
var $exno = $("input[name=exno]");
var $exname = $("input[name=exname]");
$.ajax({
type: "get",
url: "http://localhost:8080/ajax/checkGrade.jsp",
data: {
exno: $exno.val(),
exname: $exname.val()
},
dataType: "jsonp",
jsonp: "cb",
success: function(res) {
if(res.code === "1") {
alert("您的成绩:" + res.grade);
} else {
alert("没有查询到您的成绩");
}
}
})
})
五、总结:
- JSONP技术的本质是向服务器发送了一个资源请求(并不是XHR请求)。
- JSONP需要后台和前端进行配合。